private static async Task <Tuple <T, DataRetrievalMessage> > CloudOrLocal <T>(Func <Task <T> > cloudCallback, Func <Task <T> > localCallback, DataRetrievalOptions options, params Type[] dontCatch) { T result = default(T); bool attempted = false; bool successful = false; bool fallbackAttempted = false; bool fallbackSuccessful = false; while (!attempted || (attempted && !successful && options.AllowFallback && !fallbackAttempted)) { Action <bool> setSuccessful = (s) => { if (fallbackAttempted) { fallbackSuccessful = s; } else { successful = s; } }; try { if (attempted) { fallbackAttempted = true; } else { attempted = true; } if (((options.PreferredSource == Cloud) ^ fallbackAttempted) && BandwidthManager.EffectiveBandwidthOptions == BandwidthOptions.None) { setSuccessful(false); } else { result = await(((options.PreferredSource == Cloud) ^ fallbackAttempted) ? cloudCallback() : localCallback()); setSuccessful(result != null); } } catch (Exception ex) when(!dontCatch.Contains(ex.GetType())) { setSuccessful(false); } } return(new Tuple <T, DataRetrievalMessage>(result, new DataRetrievalMessage() { AttemptedSource = options.PreferredSource, AttemptSucceeded = successful, FallbackAttempted = fallbackAttempted, FallbackSucceeded = fallbackSuccessful })); }
public static async Task <Tuple <BusRoute[], DataRetrievalMessage> > GetBusRoutesForAgency(string agencyId, DataRetrievalOptions options, CancellationToken cancellationToken) { return(await CloudOrLocal(() => ApiLayer.GetBusRoutesForAgency(agencyId, cancellationToken), () => FileManager.GetBusRoutesForAgencyFromCache(agencyId), options, typeof(OperationCanceledException))); }
public static async Task <Tuple <TransitAgency[], DataRetrievalMessage> > GetTransitAgencies(DataRetrievalOptions options, CancellationToken cancellationToken) { return(await CloudOrLocal(() => ApiLayer.GetTransitAgencies(cancellationToken), () => FileManager.GetAgenciesFromCache(), options, typeof(OperationCanceledException))); }
public static async Task <Tuple <Tuple <BusStop[], string[]>, DataRetrievalMessage> > GetStopsAndShapesForRoute(string routeId, DataRetrievalOptions options, CancellationToken cancellationToken) { return(await CloudOrLocal(() => ApiLayer.GetStopsAndShapesForRoute(routeId, cancellationToken), () => FileManager.GetStopsAndShapesForRouteFromCache(routeId), options, typeof(OperationCanceledException))); }
public static async Task <Tuple <WeekSchedule, DataRetrievalMessage> > GetScheduleForStop(string id, DataRetrievalOptions options, CancellationToken cancellationToken) { return(await CloudOrLocal(() => ApiLayer.GetScheduleForStop(id, cancellationToken), () => FileManager.LoadSchedule(id), options, typeof(OperationCanceledException))); }
public static async Task <Tuple <RealtimeArrival[], DataRetrievalMessage> > GetArrivals(string stopId, DataRetrievalOptions options, CancellationToken cancellationToken) { return(await CloudOrLocal( () => ApiLayer.GetBusArrivals(stopId, cancellationToken) , () => FileManager.GetScheduledArrivals(stopId) , options, typeof(OperationCanceledException) )); }