Пример #1
0
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);
}
Пример #2
0
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);
}