* Registers the end of a "service method"; see startService(). * * @param const ServiceMethod &serviceMethod A reference to the ServiceMethod * object instantiated at the start * of the service method. */
| 151 | * of the service method. |
| 152 | */ |
| 153 | void |
| 154 | ServiceTracker::finishService(const ServiceMethod &serviceMethod) |
| 155 | { |
| 156 | // log end of service |
| 157 | stringstream message; |
| 158 | string duration_label; |
| 159 | int64_t duration = serviceMethod.timer_.elapsedUnits(stopwatchUnit_, |
| 160 | &duration_label); |
| 161 | message << serviceMethod.signature_ |
| 162 | << " finish [" << duration_label << ']'; |
| 163 | logMethod_(5, message.str()); |
| 164 | |
| 165 | // count, record, and maybe report service statistics |
| 166 | if (!serviceMethod.featureLogOnly_) { |
| 167 | |
| 168 | if (!featureCheckpoint_) { |
| 169 | |
| 170 | // lifetime counters |
| 171 | // (note: No need to lock statisticsMutex_ if not doing checkpoint; |
| 172 | // FacebookService::incrementCounter() is already thread-safe.) |
| 173 | handler_->incrementCounter("lifetime_services"); |
| 174 | |
| 175 | } else { |
| 176 | |
| 177 | statisticsMutex_.lock(); |
| 178 | // note: No exceptions expected from this code block. Wrap in a try |
| 179 | // just to be safe. |
| 180 | try { |
| 181 | |
| 182 | // lifetime counters |
| 183 | // note: Good to synchronize this with the increment of |
| 184 | // checkpoint services, even though incrementCounter() is |
| 185 | // already thread-safe, for the sake of checkpoint reporting |
| 186 | // consistency (i.e. since the last checkpoint, |
| 187 | // lifetime_services has incremented by checkpointServices_). |
| 188 | handler_->incrementCounter("lifetime_services"); |
| 189 | |
| 190 | // checkpoint counters |
| 191 | checkpointServices_++; |
| 192 | checkpointDuration_ += duration; |
| 193 | |
| 194 | // per-service timing |
| 195 | // note kjv: According to my tests it is very slightly faster to |
| 196 | // call insert() once (and detect not-found) than calling find() |
| 197 | // and then maybe insert (if not-found). However, the difference |
| 198 | // is tiny for small maps like this one, and the code for the |
| 199 | // faster solution is slightly less readable. Also, I wonder if |
| 200 | // the instantiation of the (often unused) pair to insert makes |
| 201 | // the first algorithm slower after all. |
| 202 | map<string, pair<uint64_t, uint64_t> >::iterator iter; |
| 203 | iter = checkpointServiceDuration_.find(serviceMethod.name_); |
| 204 | if (iter != checkpointServiceDuration_.end()) { |
| 205 | iter->second.first++; |
| 206 | iter->second.second += duration; |
| 207 | } else { |
| 208 | checkpointServiceDuration_.insert(make_pair(serviceMethod.name_, |
| 209 | make_pair(1, duration))); |
| 210 | } |
no test coverage detected