def crowfly_in_ridesharing_test(): response = response_pb2.Response() journey = response.journeys.add() section_crowfly = journey.sections.add() section_crowfly.type = response_pb2.CROW_FLY section_crowfly.street_network.mode = response_pb2.Car section_crowfly.duration = 42 section_crowfly.length = 43 journey.distances.car = 43 journey.durations.car = 42 section = journey.sections.add() section.type = response_pb2.PUBLIC_TRANSPORT section = journey.sections.add() section.type = response_pb2.STREET_NETWORK section.street_network.mode = response_pb2.Walking switch_back_to_ridesharing(response, True) assert section_crowfly.street_network.mode == response_pb2.Ridesharing assert journey.durations.ridesharing == 42 assert journey.durations.car == 0 assert journey.distances.ridesharing == 43 assert journey.distances.car == 0
def _do_request(self): logger = logging.getLogger(__name__) logger.debug( "requesting %s direct path from %s to %s by %s", self._path_type, self._orig_obj.uri, self._dest_obj.uri, self._mode, ) dp = self._direct_path_with_fp(self._instance) if getattr(dp, "journeys", None): if self._mode == "ridesharing": switch_back_to_ridesharing(dp, True) dp.journeys[0].internal_id = str(utils.generate_id()) logger.debug( "finish %s direct path from %s to %s by %s", self._path_type, self._orig_obj.uri, self._dest_obj.uri, self._mode, ) return dp
def call_kraken(self, request_type, request, instance, krakens_call, context=None): """ For all krakens_call, call the kraken and aggregate the responses return the list of all responses """ # TODO: handle min_alternative_journeys # TODO: call first bss|bss and do not call walking|walking if no bss in first results record_custom_parameter('scenario', 'new_default') resp = [] logger = logging.getLogger(__name__) futures = [] reqctx = copy_flask_request_context() def worker(dep_mode, arr_mode, instance, request, flask_request_id): with copy_context_in_greenlet_stack(reqctx): return ( dep_mode, arr_mode, instance.send_and_receive( request, flask_request_id=flask_request_id), ) pool = gevent.pool.Pool(app.config.get('GREENLET_POOL_SIZE', 3)) for dep_mode, arr_mode, direct_path_type in krakens_call: pb_request = create_pb_request(request_type, request, dep_mode, arr_mode, direct_path_type) # we spawn a new greenlet, it won't have access to our thread local request object so we pass the request_id futures.append( pool.spawn(worker, dep_mode, arr_mode, instance, pb_request, flask_request_id=flask.request.id)) for future in gevent.iwait(futures): dep_mode, arr_mode, local_resp = future.get() # for log purpose we put and id in each journeys self.nb_kraken_calls += 1 for idx, j in enumerate(local_resp.journeys): j.internal_id = "{resp}-{j}".format(resp=self.nb_kraken_calls, j=idx) if dep_mode == 'ridesharing': switch_back_to_ridesharing(local_resp, True) if arr_mode == 'ridesharing': switch_back_to_ridesharing(local_resp, False) fill_uris(local_resp) resp.append(local_resp) logger.debug("for mode %s|%s we have found %s journeys", dep_mode, arr_mode, len(local_resp.journeys)) return resp
def _compute_all(future_manager, request, instance, krakens_call, context): """ For all krakens_call, call the kraken and aggregate the responses return the list of all responses """ logger = logging.getLogger(__name__) logger.debug('request datetime: %s', request['datetime']) requested_dep_modes = {mode for mode, _ in krakens_call} requested_arr_modes = {mode for _, mode in krakens_call} logger.debug('requesting places by uri orig: %s dest %s', request['origin'], request['destination']) period_extremity = PeriodExtremity(request['datetime'], request['clockwise']) if context.partial_response_is_empty: context.requested_orig = PlaceByUri(future_manager=future_manager, instance=instance, uri=request['origin']) context.requested_dest = PlaceByUri(future_manager=future_manager, instance=instance, uri=request['destination']) context.requested_orig_obj = get_entry_point_or_raise( context.requested_orig, request['origin']) context.requested_dest_obj = get_entry_point_or_raise( context.requested_dest, request['destination']) context.streetnetwork_path_pool = StreetNetworkPathPool( future_manager=future_manager, instance=instance) for mode in requested_dep_modes: context.streetnetwork_path_pool.add_async_request( requested_orig_obj=context.requested_orig_obj, requested_dest_obj=context.requested_dest_obj, mode=mode, period_extremity=period_extremity, request=request, streetnetwork_path_type=StreetNetworkPathType.DIRECT, ) # if max_duration(time to pass in pt) is zero, there is no need to continue, # we return all direct path without pt if request['max_duration'] == 0: return [ context.streetnetwork_path_pool.wait_and_get( requested_orig_obj=context.requested_orig_obj, requested_dest_obj=context.requested_dest_obj, mode=mode, request=request, period_extremity=period_extremity, streetnetwork_path_type=StreetNetworkPathType.DIRECT, ) for mode in requested_dep_modes ] # We'd like to get the duration of a direct path to do some optimizations in ProximitiesByCrowflyPool and # FallbackDurationsPool. # Note :direct_paths_by_mode is a dict of mode vs future of a direct paths, this line is not blocking context.direct_paths_by_mode = context.streetnetwork_path_pool.get_all_direct_paths( ) context.orig_proximities_by_crowfly = ProximitiesByCrowflyPool( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_orig_obj, modes=requested_dep_modes, request=request, direct_paths_by_mode=context.direct_paths_by_mode, max_nb_crowfly_by_mode=request['max_nb_crowfly_by_mode'], ) context.dest_proximities_by_crowfly = ProximitiesByCrowflyPool( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_dest_obj, modes=requested_arr_modes, request=request, direct_paths_by_mode=context.direct_paths_by_mode, max_nb_crowfly_by_mode=request['max_nb_crowfly_by_mode'], ) context.orig_places_free_access = PlacesFreeAccess( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_orig_obj) context.dest_places_free_access = PlacesFreeAccess( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_dest_obj) context.orig_fallback_durations_pool = FallbackDurationsPool( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_orig_obj, modes=requested_dep_modes, proximities_by_crowfly_pool=context. orig_proximities_by_crowfly, places_free_access=context.orig_places_free_access, direct_paths_by_mode=context.direct_paths_by_mode, request=request, direct_path_type=StreetNetworkPathType.BEGINNING_FALLBACK, ) context.dest_fallback_durations_pool = FallbackDurationsPool( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_dest_obj, modes=requested_arr_modes, proximities_by_crowfly_pool=context. dest_proximities_by_crowfly, places_free_access=context.dest_places_free_access, direct_paths_by_mode=context.direct_paths_by_mode, request=request, direct_path_type=StreetNetworkPathType.ENDING_FALLBACK, ) pt_journey_pool = PtJourneyPool( future_manager=future_manager, instance=instance, requested_orig_obj=context.requested_orig_obj, requested_dest_obj=context.requested_dest_obj, streetnetwork_path_pool=context.streetnetwork_path_pool, krakens_call=krakens_call, orig_fallback_durations_pool=context.orig_fallback_durations_pool, dest_fallback_durations_pool=context.dest_fallback_durations_pool, request=request, ) completed_pt_journeys = wait_and_complete_pt_journey( future_manager=future_manager, requested_orig_obj=context.requested_orig_obj, requested_dest_obj=context.requested_dest_obj, pt_journey_pool=pt_journey_pool, streetnetwork_path_pool=context.streetnetwork_path_pool, orig_places_free_access=context.orig_places_free_access, dest_places_free_access=context.dest_places_free_access, orig_fallback_durations_pool=context.orig_fallback_durations_pool, dest_fallback_durations_pool=context.dest_fallback_durations_pool, request=request, ) # At the stage, all types of journeys have been computed thus we build the final result here res = [] if context.partial_response_is_empty: for mode in requested_dep_modes: dp = context.direct_paths_by_mode.get(mode).wait_and_get() if getattr(dp, "journeys", None): if mode == "ridesharing": switch_back_to_ridesharing(dp, True) res.append(dp) # completed_pt_journeys may contain None and res must be a list of protobuf journey res.extend((j for j in completed_pt_journeys if j)) check_final_results_or_raise(res, context.orig_fallback_durations_pool, context.dest_fallback_durations_pool) for r in res: fill_uris(r) context.partial_response_is_empty = False return res