Unexpected Error Occurred ServiceStack Redis Client - redis

Am getting an error while manipulating Hashes with Servicestack pooled redisClientsManager.
here is how i have registered the IOC
private static IRedisClientsManager redisClientsManager;
redisClientsManager = new PooledRedisClientManager("host:6379");
container.Register<IRedisClientsManager>(c => redisClientsManager);
container.Register(c => c.Resolve<IRedisClientsManager>().GetClient());
container.Register<IRepository>(c => new Repository(c.Resolve<IRedisClientsManager>()));
And Here is how am using it in Repository,
IRedisClientsManager manager;
public repository(IRedisClientsManager mgr)
{
this.manager=mgr;
}
//Method to talk to redis
using(var red = manager.getClient())
{
//do stuff with Other datatype except Hashes WORKS
}
//Error raised here
using(var redHash = manager.getClient())
{
//do stuff with Hashes DOESNT WORKS
}
Error:
Unexpected Error:* 0...., Redis response Error
Any Suggestions on how to use PooledRedisClientManager Threadsafe.!
Adding Stack trace :
Message:Unexpected reply: *0, sPort: 6379, LastCommand:
at ServiceStack.Redis.RedisNativeClient.CreateResponseError(String error)
at ServiceStack.Redis.RedisNativeClient.ParseSingleLine(String r)
at ServiceStack.Redis.RedisNativeClient.SendExpectData(Byte[][] cmdWithBinaryArgs)
at ServiceStack.Redis.RedisNativeClient.EvalShaStr(String sha1, Int32 numberKeysInArgs, Byte[][] keys)
at ServiceStack.Redis.RedisClient.ExecLuaShaAsString(String sha1, String[] keys, String[] args)
at Services.Data.Repository.GetMo(geoJ , DateTime , String ) in \Data\Repository.cs:line 169
at Services.Api.getMService.Any(getM request) in \Api\getMService.cs:line 15
at lambda_method(Closure , Object , Object )
at ServiceStack.ServiceHost.ServiceRunner`1.Execute(IRequestContext requestContext, Object instance, TRequest request)

When you get an Message:Unexpected reply Error when calling a LUA script you need to ensure that what the script is returning matches with the RedisClient API you're calling, which in this case of RedisClient.ExecLuaShaAsString() expects a string.
If you're unsure of what Type your LUA script returns you can call the more reusable ExecLuaSha which returns a complex RedisText type that can support a number of different LUA response types.

Related

Handle Azure Function input binding error

I have an Azure Function (version 4, with C# on .NET 6) that uses Cosmos DB input binding.
When the Cosmos DB input is querying for a document that does not exist it returns HTTP 404 response, however the Azure Function itself does not propagate this response and actually returns a HTTP 500 response.
How do I catch the Cosmos DB response to be able to act accordingly in the Azure function?
Or in other words - how do I perform error/http-response handling on the function's input bindings?
I hoped validating that the input argument is not null would be it,
and also tried to validate that the IEnumerable response is not empty,
but it turns out it doesn't even enter the code in the function when it gets the Cosmos DB 404 response. The function just breaks and the returns HTTP 500:
[FunctionName("GetItems")]
public IActionResult GetItems(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
[CosmosDB(
databaseName: "my-db",
containerName: "my-container",
Connection = "my-conn-string",
PartitionKey = "my-pk")] IEnumerable<MyItem> items)
{
_logger.LogInformation("Get list of items");
if (items == null)
{
_logger.LogInformation("Items object is null");
return new NotFoundResult();
}
var itemsList = items as List<MyItem>;
if (itemsList.Count == 0)
{
_logger.LogInformation("Items object is missing");
return new NotFoundResult();
}
return new OkObjectResult(itemsList.First());
}
}
Below is the example of input binding error.
[FunctionName("EventHubTrigger")]
[FixedDelayRetry(5, "00:00:10")]
public static async Task Run([EventHubTrigger("myHub", Connection = "EventHubConnection")] EventData[] events, ILogger log)
{
// ...
}
and Here is the complete documentation on Handling binding errors.

Jersey response.readEntity(...) sometimes returns null

Consider this snippet from my REST client (Jersey 2.26). It's used to post objects and return the response object. If the REST server returns an error (status >= 400), then instead of returning an entity of type T I want to read an entity of type ErrorMessage and throw an exception containing the error message object.
protected <T> T post(final Class<T> type,
final Object entity,
final Map<String, Object> queryParams,
final String methodPath,
final Object... arguments) {
return postResponse(
getInvocationBuilderJson(methodPath,
queryParams,
arguments),
entity
).readEntity(type);
}
protected Response postResponse(final Invocation.Builder invocationBuilder,
final Object entity) {
return handleErrors(
invocationBuilder.post(Entity.entity(entity,
MediaType.APPLICATION_JSON_TYPE))
);
}
protected Response handleErrors(final Response response) {
if (response.getStatus() >= 400) {
throw new InvocationException(response.readEntity(ErrorMessage.class));
}
return response;
}
If no error occurs (status < 400), then my object of type T is returned as expected. However, when an error does occur, response.readEntity(ErrorMessage.class) returns null. But (and this is the strange part), this does get me data (at the handleErrors method):
byte[] data = readAllBytes((InputStream) response.getEntity());
I could use that and deserialize it manually.. but I would first like to know if there are any options to fix this without implementing workarounds.
After switching from the default MOXy JSON (de)serializer (we now are using a GSON provider) the problem was resolved.
We recently had a similar issue with JSON-B. There is turned out we had to add a getter and setter on our error object on order to (de)serialize the object.

dryioc controller.service is resolved during setup, not during api call

I have been searching a lot, both online, and debugging, re-read docs for dryioc and took a look at the samples. I don't think my issues lies with dryioc, or maybe I'm overlooking a silly mistake.
Project setup => service => owin + webapi2
Using attributerouting, swagger and apiversioning
This is how I setup my container
private IContainer SetupDependencyInjection(HttpConfiguration config)
{
var container = new Container();
container.WithWebApi(config, throwIfUnresolved: type => typeIsController());
container.RegisterWebApiControllers(config);
container.Register<IObjectFactory, ObjectFactory>(Reuse.Singleton);
RegisterStoreServices(container);
RegisterMetadata(container);
var validate = container.Validate();
var verify = container.VerifyResolutions();
if (validate.Any() || verify.Any())
{
throw new Exception("Error occured while setting up service dependencies.");
}
using (var c = container.OpenScope(Reuse.WebRequestScopeName))
{
var songController = c.Resolve<Musify.WebApi.Controllers.v1._0.SongsController>();
var GenresController = c.Resolve<Musify.WebApi.Controllers.v1._0.GenresController>();
}
return container;
}
Both RegisterStoreServices and RegisterMetadata only contain singleton or transient registrations.
When I try to call a controller method on my API controller, I get the following error
{
"message": "An error has occurred.",
"exceptionMessage": "An error occurred when trying to create a controller of type 'SongsController'. Make sure that the controller has a parameterless public constructor.",
"exceptionType": "System.InvalidOperationException",
"stackTrace": " at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
"innerException": {
"message": "An error has occurred.",
"exceptionMessage": "Unable to resolve Musify.Api.Service.Data.ISongRepository as parameter \"songRepository\"\r\n in scoped Musify.WebApi.Controllers.v1._0.SongsController.\r\nWhere no service registrations found\r\n and number of Rules.FallbackContainers: 0\r\n and number of Rules.UnknownServiceResolvers: 0",
"exceptionType": "DryIoc.ContainerException",
"stackTrace": " at DryIoc.Throw.It(Int32 error, Object arg0, Object arg1, Object arg2, Object arg3)\r\n at DryIoc.Container.ThrowUnableToResolve(Request request)\r\n at DryIoc.Container.DryIoc.IContainer.ResolveFactory(Request request)\r\n at DryIoc.ReflectionFactory.CreateExpressionOrDefault(Request request)\r\n at DryIoc.Factory.GetExpressionOrDefault(Request request)\r\n at DryIoc.Factory.GetDelegateOrDefault(Request request)\r\n at DryIoc.Container.ResolveAndCacheDefaultDelegate(Type serviceType, Boolean ifUnresolvedReturnDefault, IScope scope)\r\n at DryIoc.Container.DryIoc.IResolver.Resolve(Type serviceType, Boolean ifUnresolvedReturnDefault)\r\n at DryIoc.WebApi.DryIocDependencyScope.GetService(Type serviceType)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
}
}
I know that in a lot of cases, this is because the service is not registered, but I did.
container.Register<ISongRepository, SongRepository>(Reuse.Singleton);
As you can see in the fist code snippet, I valide, verify, and I even tried container.openscope, to see if the container was registered. And on the container, I can see the songrepository being filled in as well.
So I'm guessing, somehow, the webapi doesn't use the controllers inujected into the container.
Am I doing something wrong in my dependency setup?
public void Configuration(IAppBuilder appBuilder)
{
SetupLogging();
var config = new HttpConfiguration();
SetupRouting(config);
SetupVersioning(config);
SetupJson(config);
SetupDocumentation(config);
SetupDependencyInjection(config);
appBuilder.UseWebApi(config);
appBuilder.UseErrorPage(ErrorPageOptions.ShowAll);
}
I'm not sure if it matters, but I'm setting the container up, after everything else has been configured.
After some messing around, I got it working after adding the lines marked with //this
var container = SetupDependencyInjection(config);
appBuilder.UseDryIocOwinMiddleware(container); //this
appBuilder.UseWebApi(config);
appBuilder.UseDryIocWebApi(config); //this
I would like an explenation though, if someone could give me one.
Because on another post, I read that a guy had problems because of using both UseWebApi and UseDryIocWebApi.
But without the OwinMiddleware, it still wouldn't work. So what do both of these functions accomplish?
Or did I use a "wrong fix"?

Timeout using ServiceStack.Client

I have been using service stack via AJAX calls for some time without issue, but have recently created a quick winforms app which utilizes the service stack client (specifically JsonServiceClient).
However - I have hit a problem whereby I consistently get a timeout on a call which works successfully on the the first TWO attempts. It looks like either the service stack client is holding on to some resource, or I am using the client in the wrong way. It only occurs when running against a remote service (works every time on a local machine). Here is my code, and the exception:
var url = "http://www.TestServer.com/api";
var taskId = Guid.Parse("30fed418-214b-e411-80c1-22000a5b9fe5");
var email = "admin#example.com";
using (var client = new JsonServiceClient(url))
{
var result = client.Send(new Authenticate {UserName = "username", Password = "Password01", RememberMe = true});
client.Put(new AssignTask { AdminTaskId = taskId, Assignee = email });//Call #1 - works fine
client.Put(new AssignTask { AdminTaskId = taskId, Assignee = email });//Call #2 - works fine
try
{
client.Put(new AssignTask { AdminTaskId = taskId, Assignee = email });//Call #3 - works fine
}
catch (WebException ex)
{
//Times out every time
//at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
//at System.Net.HttpWebRequest.GetRequestStream()
//at ServiceStack.Net40PclExport.GetRequestStream(WebRequest webRequest)
//at ServiceStack.ServiceClientBase.<>c__DisplayClassa.<SendRequest>b__9(HttpWebRequest client)
//at ServiceStack.ServiceClientBase.PrepareWebRequest(String httpMethod, String requestUri, Object request, Action`1 sendRequestAction)
//at ServiceStack.ServiceClientBase.SendRequest(String httpMethod, String requestUri, Object request)
//at ServiceStack.ServiceClientBase.Send[TResponse](String httpMethod, String relativeOrAbsoluteUrl, Object request)
//at ServiceStack.ServiceClientBase.Put[TResponse](String relativeOrAbsoluteUrl, Object requestDto)
//at ServiceStack.ServiceClientBase.Put(Object requestDto)
//at SSClientIssue.Program.Main(String[] args) in c:\Users\David\Documents\Visual Studio 2013\Projects\SSClientIssue\SSClientIssue\Program.cs:line 27
throw;
}
}
After the timeout, I can close and reload the app (server stays up), and then get same behavior again (two successful calls). IIS logs show that the 3rd call does not make it to the server, so looks like a Client issue.
I have been looking at this for 8 hours and I think my eyes are starting to bleed...If anyone can help I will buy you a beer!
The issue is due to your ServiceClient requests not specifying a known response type.
Response types can either be marked on the Request DTO using the IReturn<T> marker (recommended):
public class GetAllAdminUsernamesRequest : IReturn<List<string>> { ... }
By adding this on the Request DTO, the ServiceClient is able to automatically infer and convert the response, e.g:
List<string> response = client.Get(new GetCurrentAdminUserAdminTasks());
Otherwise an alternative to specifying the Response on the Request DTO, is to specify it on the call-site, e.g:
List<string> response = client.Get<List<string>>(new GetCurrentAdminUserAdminTasks());
If you don't do this the Response is unknown so the ServiceClient will just return the underlying HttpWebResponse so you can inspect the response yourself.
HttpWebResponse tasks = client.Get(new GetCurrentAdminUserAdminTasks());
In order to be able to inspect and read from the HttpWebResponse the response cannot be disposed by the ServiceClient, so it's up to the call-site making the request to properly dispose of it, i.e:
using (HttpWebResponse tasks = client.Get(new GetCurrentAdminUserAdminTasks())) {}
using (HttpWebResponse adminUsers = client.Get(new GetAllAdminUsernames())) {}
try
{
using (client.Put(new AssignTask { AdminTaskId = taskId, Assignee = user })) {}
using (client.Put(new AssignTask { AdminTaskId = taskId, Assignee = user })) {}
using (client.Put(new AssignTask { AdminTaskId = taskId, Assignee = user })) {}
using (client.Put(new AssignTask { AdminTaskId = taskId, Assignee = user })) {}
}
...
Disposing of your WebResponses responses will resolve your issue.
If you don't do this the underlying WebRequest will throttle open connections and only let a limited number of simultaneous connections through at any one time, possibly as a safe-guard to prevent DDOS attacks. This is what keeps the underlying connections open and WebRequest to block, waiting for them to be released.

The underlying connection was closed error while using .Include on EF objects

Following line of code gives me an error saying "The underlying connection was closed".
return this.repository.GetQuery<Countries>().Include(g => g.Cities).AsEnumerable().ToList();
But if I remove .Include(g => g.cities) it works fine.
this code is written in one of the operation in my WCF service, and I try to test it using WCF test client. I tried by calling this operation from MVC application also, and the same issue was occurring there too.
Also, i am using generic repository with entity framework
Repository code (only few important extract)
Constructor:
public GenericRepository(DbContext objectContext)
{
if (objectContext == null)
throw new ArgumentNullException("objectContext");
this._dbContext = objectContext;
this._dbContext.Configuration.LazyLoadingEnabled = false;
this._dbContext.Configuration.ProxyCreationEnabled = false;
}
GetQuery method:
public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
{
var entityName = GetEntityName<TEntity>();
return ((IObjectContextAdapter)DbContext).ObjectContext.CreateQuery<TEntity>(entityName);
}
Attempt#1
Created following overloads in repository code:
public IQueryable<TEntity> GetQuery<TEntity>(params string[] includes) where TEntity : class
{
var entityName = GetEntityName<TEntity>();
IQueryable<TEntity> query = ((IObjectContextAdapter)DbContext).ObjectContext.CreateQuery<TEntity>(entityName);
foreach(string include in includes)
{
query = query.Include(include);
}
return query;
}
public IQueryable<TEntity> GetQuery<TEntity>(Expression<Func<TEntity, bool>> predicate, params string[] includes) where TEntity : class
{
return GetQuery<TEntity>(includes).Where(predicate);
}
WCF is now trying to execute following line of code:
return this.repository.GetQuery<Countries>("Cities").AsEnumerable().ToList()
But it still gives the same error of "The underlying connection was closed". I tested it in WCF test client. However, when I debug the repository code it shows the navigation object getting included in result, but the issue seems occurring while trying to pass the output to client (WCF test client, or any other client)
After looking at the code you've now posted, I can conclude that, indeed, your DbContext is being closed at the end of the GetQuery method, and is thus failing when you try to use include. What you might want to do to solve it is to have an optional params variable for the GetQuery method that will take in some properties to be included, and just do the include right in the GetQuery method itself.