public async Task <ResultSingle <Permit <UserT> > > RenewAccessAsync( Dictionary <string, object> data = null) { Notifier?.BeginQuery(); Permit.UseRefreshToken(); ResultSingle <Permit <UserT> > result = await Send <Permit <UserT>, ResultSingle <Permit <UserT> >, Permit <UserT> >( new HttpRequest <Permit <UserT>, ResultSingle <Permit <UserT> > >(GetAsync), Permit, true, data, null, false); UpdatePermit(result); Notifier?.EndQuery(); return(result); }
private async Task <ResultT> TrySend <PayloadT, ResultT, ResultReturnT>( HttpRequest <PayloadT, ResultT> request, PayloadT seed, bool keyRequest, IDictionary <string, object> data, string subPath = null, bool doCache = true) where PayloadT : ICloudObject, new() where ResultT : Result <ResultReturnT>, new() { // Try-send is used to send after a session has been established // it attaches the JWT token, attempts retry if failed and also // handle cacheing ResultT result = new ResultT(); for (int attempt = 0; attempt < RetryCount; attempt++) { result = await Send <PayloadT, ResultT, ResultReturnT>( request, seed, keyRequest, data, subPath, doCache); switch (result.Code) { // Manage transport issues at this level case ServerStatus.NEST_RESULT_ERROR_TRANSPORT_BAD_REQUEST: case ServerStatus.NEST_RESULT_ERROR_TRANSPORT_UNAUTHORIZED: case ServerStatus.NEST_RESULT_ERROR_TRANSPORT_FORBIDDEN: return(result); case ServerStatus.NEST_RESULT_ERROR_TRANSPORT_TOKEN_EXPIRED: if (Permit != null && AutoTokenRenew) { // The token has expired. Renew is auto-renew option // has been requested. Permit.UseRefreshToken(); ResultSingle <Permit <UserT> > renewResult = await GetAsync(Permit, CreateRequest(Permit, true, data)); if (renewResult.Code < 0) { return(result); } UpdatePermit(renewResult); } else { return(result); } break; case ServerStatus.NEST_RESULT_ERROR_TRANSPORT: { if (attempt < RetryCount) { if (Notifier != null && !Notifier.CanProgress(attempt + 1)) { // Ask the notifier whether its okay to proceed return(result); } // Wait period grows after each re-try. if interval is 2 seconds then // the each try will be in 2, 4, 8 second intervals etc. // (Exponential back-off) int waitIntervalSecs = (int)Math.Pow( RetryBaseIntervalInSecs, attempt + 1); Notifier?.Waiting(waitIntervalSecs); Debug.Print("Re-attempt {0}, waiting for - {1} seconds ...", attempt + 1, waitIntervalSecs); Task.Delay(waitIntervalSecs * 1000).Wait(); } } break; default: // Let the application handle higher errors return(result); } } return(result); }