void reversal (tdata_t *tdata, router_request_t *req, bool verbose) { /* Initialize router */ router_t router; router_setup (&router, tdata); char result_buf[OUTPUT_LEN]; router_route (&router, req); if (verbose) { router_request_dump (&router, req); router_result_dump(&router, req, result_buf, OUTPUT_LEN); printf("%s", result_buf); } /* Repeat search in reverse to compress transfers */ uint32_t n_reversals = req->arrive_by ? 1 : 2; /* but do not reverse requests starting on board (they cannot be compressed, earliest arrival is good enough) */ if (req->start_trip_trip != NONE) n_reversals = 0; for (uint32_t i = 0; i < n_reversals; ++i) { router_request_reverse (&router, req); // handle case where route is not reversed router_route (&router, req); if (verbose) { printf ("Repeated search with reversed request: \n"); router_request_dump (&router, req); router_result_dump(&router, req, result_buf, OUTPUT_LEN); printf("%s", result_buf); } } /* Output only final result in non-verbose mode */ if (!verbose) { router_result_dump(&router, req, result_buf, OUTPUT_LEN); printf("%s", result_buf); } router_teardown(&router); }
int main(int argc, char **argv) { /* SETUP */ // logging setlogmask(LOG_UPTO(LOG_DEBUG)); openlog(PROGRAM_NAME, LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER); syslog(LOG_INFO, "worker starting up"); // load transit data from disk tdata_t tdata; tdata_load(RRRR_INPUT_FILE, &tdata); // initialize router router_t router; router_setup(&router, &tdata); //tdata_dump(&tdata); // debug timetable file format // establish zmq connection zctx_t *zctx = zctx_new (); void *zsock = zsocket_new(zctx, ZMQ_REQ); uint32_t zrc = zsocket_connect(zsock, WORKER_ENDPOINT); if (zrc != 0) exit(1); // signal to the broker/load balancer that this worker is ready zframe_t *frame = zframe_new (WORKER_READY, 1); zframe_send (&frame, zsock, 0); syslog(LOG_INFO, "worker sent ready message to load balancer"); /* MAIN LOOP */ uint32_t request_count = 0; char result_buf[OUTPUT_LEN]; while (true) { zmsg_t *msg = zmsg_recv (zsock); if (!msg) // interrupted (signal) break; if (++request_count % 100 == 0) syslog(LOG_INFO, "worker received %d requests\n", request_count); // only manipulate the last frame, then send the recycled message back to the broker zframe_t *frame = zmsg_last (msg); if (zframe_size (frame) == sizeof (router_request_t)) { router_request_t *preq; preq = (router_request_t*) zframe_data (frame); router_request_t req = *preq; // protective copy, since we're going to reverse it D printf ("Searching with request: \n"); I router_request_dump (&router, &req); router_route (&router, &req); // repeat search in reverse to compact transfers uint32_t n_reversals = req.arrive_by ? 1 : 2; //n_reversals = 0; // DEBUG turn off reversals for (uint32_t i = 0; i < n_reversals; ++i) { router_request_reverse (&router, &req); // handle case where route is not reversed D printf ("Repeating search with reversed request: \n"); D router_request_dump (&router, &req); router_route (&router, &req); } // uint32_t result_length = router_result_dump(&router, &req, result_buf, OUTPUT_LEN); struct plan plan; router_result_to_plan (&plan, &router, &req); plan.req.time = preq->time; // restore the original request time uint32_t result_length = render_plan_json (&plan, router.tdata, result_buf, OUTPUT_LEN); zframe_reset (frame, result_buf, result_length); } else { syslog (LOG_WARNING, "worker received reqeust with wrong length"); zframe_reset (frame, "ERR", 3); } // send response to broker, thereby requesting more work zmsg_send (&msg, zsock); } /* TEAR DOWN */ syslog(LOG_INFO, "worker terminating"); // frame = zframe_new (WORKER_LEAVING, 1); // zframe_send (&frame, zmq_sock, 0); // syslog(LOG_INFO, "departure message sent to load balancer"); // zmsg_t *msg = zmsg_recv (zmq_sock); router_teardown(&router); tdata_close(&tdata); zctx_destroy (&zctx); //zmq_close(socket) necessary before context destroy? exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { router_request_t req; router_request_initialize (&req); char *tdata_file = RRRR_INPUT_FILE; char *gtfsrt_file = NULL; char *gtfsrt_alerts_file = NULL; bool verbose = false; int opt = 0; while (opt >= 0) { opt = getopt_long(argc, argv, "adrhD:s:S:o:f:t:V:m:Q:x:y:z:w:A:g:G:T:v", long_options, NULL); if (opt < 0) continue; switch (opt) { case 'T': tdata_file = optarg; break; case 'g': gtfsrt_file = optarg; break; case 'G': gtfsrt_alerts_file = optarg; break; case 'v': verbose = true; break; case 'h': goto usage; } } /* SETUP */ // load transit data from disk tdata_t tdata; tdata_load(tdata_file, &tdata); optind = 0; opt = 0; while (opt >= 0) { opt = getopt_long(argc, argv, "adrhD:s:S:o:f:t:V:m:Q:x:y:z:w:A:g:G:T:v", long_options, NULL); parse_request(&req, &tdata, NULL, opt, optarg); } if (req.from == NONE || req.to == NONE) goto usage; if (req.from == req.to) { fprintf(stderr, "Dude, you are already there.\n"); exit(-1); } if (req.from >= tdata.n_stops || req.to >= tdata.n_stops) { fprintf(stderr, "Invalid stopids in from and/or to.\n"); exit(-1); } if (req.time_rounded && !(req.arrive_by)) { req.time++; // Round time upwards when departing after a requested time } req.time_rounded = false; // load gtfs-rt file from disk if (gtfsrt_file != NULL || gtfsrt_alerts_file != NULL) { RadixTree *tripid_index = rxt_load_strings_from_tdata (tdata.trip_ids, tdata.trip_id_width, tdata.n_trips); if (gtfsrt_file != NULL) { tdata_clear_gtfsrt (&tdata); tdata_apply_gtfsrt_file (&tdata, tripid_index, gtfsrt_file); } if (gtfsrt_alerts_file != NULL) { RadixTree *routeid_index = rxt_load_strings_from_tdata (tdata.route_ids, tdata.route_id_width, tdata.n_routes); RadixTree *stopid_index = rxt_load_strings_from_tdata (tdata.stop_ids, tdata.stop_id_width, tdata.n_stops); tdata_clear_gtfsrt_alerts(&tdata); tdata_apply_gtfsrt_alerts_file (&tdata, routeid_index, stopid_index, tripid_index, gtfsrt_alerts_file); } } // initialize router router_t router; router_setup(&router, &tdata); //tdata_dump(&tdata); // debug timetable file format char result_buf[OUTPUT_LEN]; router_route (&router, &req); if (verbose) { router_request_dump (&router, &req); router_result_dump(&router, &req, result_buf, OUTPUT_LEN); printf("%s", result_buf); } // repeat search in reverse to compact transfers uint32_t n_reversals = req.arrive_by ? 1 : 2; // but do not reverse requests starting on board (they cannot be compressed, earliest arrival is good enough) if (req.start_trip_trip != NONE) n_reversals = 0; // n_reversals = 0; // DEBUG turn off reversals for (uint32_t i = 0; i < n_reversals; ++i) { router_request_reverse (&router, &req); // handle case where route is not reversed router_route (&router, &req); if (verbose) { printf ("Repeated search with reversed request: \n"); router_request_dump (&router, &req); router_result_dump(&router, &req, result_buf, OUTPUT_LEN); printf("%s", result_buf); } } /* Output only final result in non-verbose mode */ if (!verbose) { router_result_dump(&router, &req, result_buf, OUTPUT_LEN); printf("%s", result_buf); } sdl_main(&router, &tdata, &req); router_teardown(&router); tdata_close(&tdata); exit(EXIT_SUCCESS); usage: printf("Usage:\n%s [-r(andomize)] [--from-idx from_stop] [--to-idx to_stop] [-a(rrive)] [-d(epart)] [-D YYYY-MM-DDThh:mm:ss] [-g gtfsrt.pb] [-T timetable.dat]\n", argv[0]); exit(-2); }