Run the worker thread for a GKE batch job.
| 265 | |
| 266 | /// Run the worker thread for a GKE batch job. |
| 267 | void worker(boost::program_options::variables_map const& vm) { |
| 268 | std::cout << "Running in worker mode" << std::endl; |
| 269 | |
| 270 | if (vm.count("project") == 0 or vm["project"].as<std::string>().empty()) { |
| 271 | throw std::runtime_error("the `schedule` action requires --subscription"); |
| 272 | } |
| 273 | if (vm.count("subscription") == 0) { |
| 274 | throw std::runtime_error("the `schedule` action requires --subscription"); |
| 275 | } |
| 276 | auto const concurrency = vm["concurrency"].as<int>(); |
| 277 | auto const project_id = vm["project"].as<std::string>(); |
| 278 | auto const subscription_id = vm["subscription"].as<std::string>(); |
| 279 | |
| 280 | using namespace std::chrono_literals; |
| 281 | using std::chrono::duration_cast; |
| 282 | using std::chrono::milliseconds; |
| 283 | auto const subscription = pubsub::Subscription(project_id, subscription_id); |
| 284 | auto subscriber = pubsub::Subscriber(pubsub::MakeSubscriberConnection( |
| 285 | subscription, |
| 286 | google::cloud::Options{} |
| 287 | .set<pubsub::MaxOutstandingMessagesOption>(concurrency) |
| 288 | .set<pubsub::MaxOutstandingBytesOption>(concurrency * 1024) |
| 289 | .set<pubsub::MaxConcurrencyOption>(concurrency) |
| 290 | .set<pubsub::MaxDeadlineTimeOption>(300s) |
| 291 | .set<google::cloud::GrpcBackgroundThreadPoolSizeOption>( |
| 292 | concurrency))); |
| 293 | |
| 294 | std::atomic<std::int64_t> latency{0}; |
| 295 | std::atomic<std::int64_t> attempts{0}; |
| 296 | std::atomic<std::int64_t> counter{0}; |
| 297 | auto handler = [&, cl = gcs::Client::CreateDefaultClient().value()]( |
| 298 | pubsub::Message const& m, pubsub::AckHandler h) { |
| 299 | auto const start = std::chrono::steady_clock::now(); |
| 300 | process_one_item(cl, m); |
| 301 | auto const elapsed = std::chrono::steady_clock::now() - start; |
| 302 | latency.fetch_add(duration_cast<milliseconds>(elapsed).count()); |
| 303 | attempts.fetch_add(h.delivery_attempt()); |
| 304 | ++counter; |
| 305 | std::move(h).ack(); |
| 306 | }; |
| 307 | |
| 308 | using namespace std::chrono_literals; |
| 309 | using google::cloud::StatusCode; |
| 310 | auto session = subscriber.Subscribe(handler); |
| 311 | auto total = counter.exchange(0); |
| 312 | auto mean = [&total](std::int64_t v) -> std::int64_t { |
| 313 | if (total == 0) return 0; |
| 314 | return v / total; |
| 315 | }; |
| 316 | while (session.wait_for(30s) == std::future_status::timeout) { |
| 317 | auto last = counter.exchange(0); |
| 318 | total += last; |
| 319 | std::cout << "Processed " << last << " work items" |
| 320 | << ", latency=" << mean(latency.load()) |
| 321 | << ", attempts=" << mean(attempts.load()) << ", count=" << total |
| 322 | << std::endl; |
| 323 | } |
| 324 |
nothing calls this directly
no test coverage detected