c# - No connection is available to service this operation: when using Azure Redis Cache -


i have following code use information cache. dont know if maybe app opening many connections or error due transient failure on azure redis cache.

this stack trace

[redisconnectionexception: no connection available service operation: userprofileinformation|globaladmin@xx.onmicrosoft.com] stackexchange.redis.connectionmultiplexer.executesyncimpl(message message, resultprocessor1 processor, serverendpoint server) in c:\teamcity\buildagent\work\3ae0647004edff78\stackexchange.redis\stackexchange\redis\connectionmultiplexer.cs:1922 stackexchange.redis.redisbase.executesync(message message, resultprocessor1 processor, serverendpoint server) in c:\teamcity\buildagent\work\3ae0647004edff78\stackexchange.redis\stackexchange\redis\redisbase.cs:80 stackexchange.redis.redisdatabase.stringget(rediskey key, commandflags flags) in c:\teamcity\buildagent\work\3ae0647004edff78\stackexchange.redis\stackexchange\redis\redisdatabase.cs:1431 xx.utils.samplestackexchangeredisextensions.get(idatabase cache, string key) in c:\proyectos\xx\xx\utils\samplestackexchangeredisextensions.cs:20
xx.cache.userprofile.getuserprofile(string identityname) in c:\proyectos\xx\xx\cache\userprofile.cs:22
x.controllers.userprofilecontroller.getpropertiesforuser() in c:\proyectos\xx\xx\controllers\userprofilecontroller.cs:16
lambda_method(closure , controllerbase , object[] ) +61
system.web.mvc.actionmethoddispatcher.execute(controllerbase controller, object[] parameters) +14

and code

   public static models.userprofile getuserprofile(string identityname)         {             /// needs cached every user because every user can have different modules enabled.              var cachekeyname = "userprofileinformation|" + identityname;             idatabase cache = cacheconnectionhelper.connection.getdatabase();             models.userprofile userprofile = new models.userprofile();             object obj = cache.get(cachekeyname);             string userprofilestring;             if (obj != null)             {                 //get string cache                 userprofilestring = obj.tostring();                  //conver string our object                 userprofile = jsonconvert.deserializeobject<models.userprofile>(userprofilestring);                 return userprofile;             }             else             {                 #region user profile ad                 uri serviceroot = new uri(settingshelper.azureadgraphapiendpoint);                 var token = apptoken.getapptoken();                  activedirectoryclient adclient = new activedirectoryclient(                  serviceroot,                  async () => await apptoken.getapptokenasync());                  string userobjectid = claimsprincipal.current.findfirst("http://schemas.microsoft.com/identity/claims/objectidentifier").value;                  microsoft.azure.activedirectory.graphclient.application app = (microsoft.azure.activedirectory.graphclient.application)adclient.applications.where(                     => a.appid == settingshelper.clientid).executesingleasync().result;                 if (app == null)                 {                     throw new applicationexception("unable reference application in azure ad.");                 }                  string requesturl = string.format("https://graph.windows.net/{0}/users/{1}?api-version=1.5", settingshelper.tenant, identityname);                 httpclient hc = new httpclient();                 hc.defaultrequestheaders.authorization = new system.net.http.headers.authenticationheadervalue("bearer", token);                 httpresponsemessage hrm = hc.getasync(new uri(requesturl)).result;                  if (hrm.issuccessstatuscode)                 {                     models.userprofile currentuserprofile = jsonconvert.deserializeobject<models.userprofile>(hrm.content.readasstringasync().result);                      //convert object json string                     userprofilestring = jsonconvert.serializeobject(currentuserprofile);                      cache.set(cachekeyname, userprofilestring, timespan.fromminutes(settingshelper.cacheuserprofileminutes));                     return currentuserprofile;                 }                 else                 {                     return null;                 }                 #endregion             }         }     public static class samplestackexchangeredisextensions     {         public static t get<t>(this idatabase cache, string key)         {             return deserialize<t>(cache.stringget(key));         }          public static object get(this idatabase cache, string key)         {             return deserialize<object>(cache.stringget(key));         }          public static void set(this idatabase cache, string key, object value, timespan expiration)         {             cache.stringset(key, serialize(value), expiration);         }          static byte[] serialize(object o)         {             if (o == null)             {                 return null;             }             binaryformatter binaryformatter = new binaryformatter();             using (memorystream memorystream = new memorystream())             {                 binaryformatter.serialize(memorystream, o);                 byte[] objectdataasstream = memorystream.toarray();                 return objectdataasstream;             }         }          static t deserialize<t>(byte[] stream)         {             binaryformatter binaryformatter = new binaryformatter();             if (stream == null)                 return default(t);              using (memorystream memorystream = new memorystream(stream))             {                 t result = (t)binaryformatter.deserialize(memorystream);                 return result;             }         } 

questions are: 1. how can control connection exception 1 shown, user doesnt error , instead goes db if redis unavailable? 2. there anyway retry transient fault handling azure redis cache?

i believe these transient errors. have seen many of these in application logs before implemented simple retry logic. had quite few timeouts. simple retry logic, plus adding synctimeout=3000 redis connection string resolved all these me.

public object get(string key) {     return deserialize(cache.stringget(key)); }  public object getwithretry(string key, int wait, int retrycount) {     int = 0;         {         try         {             return get(key);         }         catch (exception)         {             if (i < retrycount + 1)             {                 thread.sleep(wait);                 i++;             }             else throw;         }     }     while (i < retrycount + 1);     return null; } 

Comments