ServiceStack Redis Messaging - IMessage? - servicestack

I would like to use Redis to invoke a service operation on my Service Stack service.
I have created a simple DTO as the message request, and am registering the message service as per the demo pages:
var messageService = m_Container.Resolve<RedisMqServer>();
messageService.RegisterHandler<SubscribeAddressRequest>(x => ServiceController.ExecuteMessage(x) );
messageService.Start();
ServiceStack actually receives these messages, but I get the following error (from my Container):
No component for supporting the service ServiceStack.Messaging.IMessage was found.
This is very odd, why is ServiceStack asking for a dependency to be injected as an IMessage? I have not registered any providers for an IMessage so I understand that this would fail, but I do not see any providers. I am registering the following types:
string[] RedisHosts = new string[] { (string)ConfigurationManager.AppSettings["RedisHost"] };
container.Register(
Component.For<IRedisClientsManager>().ImplementedBy<PooledRedisClientManager>().DependsOn(new { poolSize = 1000, poolTimeOutSeconds = 1, readWriteHosts = RedisHosts }),
Component.For<RedisMqServer>(),
Component.For<IMessageQueueClient>().UsingFactoryMethod((k, c) =>
{
return k.Resolve<RedisMqServer>().CreateMessageQueueClient();
})
);

It looks like this is an issue with the Container you're using, I'm not sure why it's asking for this, it may have something to do with your IOC's auto bootstrap scanning process, but it's not something you'd want resolved from the IOC. To help with the investigation, the type in the RegisterHandler callback is of IMessage<T>, e.g:
messageService.RegisterHandler<SubscribeAddressRequest>(x // <- IMessage<T>

I have found the cause of the issue, which is that my IoC Container (Castle Windsor) is injecting the RequestFilter and ResponseFilter on a RedisMqServer with a dynamic Func with the aim of resolving an IMessage from the container (when using TypedFactoryFacility).
This is because of the delegate-factory which is part of the TypedFactoryFacility (I usually use interface-factories).
I got round this by disabling the automatic enabling of the Castle Windsor delegate-factory when using the Typed Factory Facility:
Remove components in Castle Windsor 3

Related

.NET Core 2.0 HttpClient Singleton throwing 502

I have a web application acting as a gateway to a variety of internal services. These services are consumed by using a single instance of HttpClient, instantiated at startup (i.e. Startup.cs)
After a certain period of time, something is causing our HttpClient to stop hitting our APIs and immediately fail with HTTP 502 errors for every call using that client. (Note that I can still hit our APIs using other means, such as Postman)
Also be aware that this is all deployed to a variety of AppServices in Azure.
Any ideas as to what could corrupt HttpClient in this manner?
Thanks,
-Tim
This error is usually given when you are behind a proxy server.
If you are using a proxy you will probably have to authenticate the http client again.
Another possibility is to generate the Singleton instance again when it gives an error, for Example Singleton.killInstance(); If your implementation is like this:
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
public static void Singleton killInstance()
{
instance == null
}
}
Whatever the error might be, your httpclient request is causing your web server to crash. In order to investigate it, you need to go to to the Event Viewer of your AppService.
Here are the steps to launch the event viewer:
Go to Kudu management site of your website (ie https://{sitename}.scm.azurewebsites.net
Open menu item: Tools => Support
Choose relevant Azure AD Directory of your website
Click on Analyze => Event Viewer.
Check the error messages

Servicestack Multitenancy dynamic plugins

We are moving from an on premise-like application to a multi tenant cloud application.
for my web application we made a very simple interface based on IPlugin, to create a plugin architecture. (customers can have/install different plugins)
public interface IWebPlugin : IPlugin
{
string ContentBaseUrl { set; get; }
}
We have some plugins that would normally be loaded in on startup. Now i'm migrating the code to load at the beginning of a request (the Register function is called on request start), and scope everything inside this request.
It's not ideal but it would bring the least impact on the plugin system for now.
I could scope the Container by making an AppHost child container which would stick to the request:
Container IHasContainer.Container
{
get
{
if (HasStarted)
return ChildContainer;
return base.Container;
}
}
public Container ChildContainer
{
get { return HttpContext.Current.Items.GetOrAdd<Container>("ChildContainer", c => Container.CreateChildContainer()); }
}
problem case
Now im trying to make plugins work that actually add API services.
appHost.Routes.Add<GetTranslations>("/Localizations/translations", ApplyTo.Get);
But this service is unreachable (and not visible in metadata). How do i make it reachable?
I see you execute the following in ServiceController AfterInit. Re-executing this still wouldnt make it work.
//Copied from servicestack repo
public void AfterInit()
{
//Register any routes configured on Metadata.Routes
foreach (var restPath in appHost.RestPaths)
{
RegisterRestPath(restPath);
//Auto add Route Attributes so they're available in T.ToUrl() extension methods
restPath.RequestType
.AddAttributes(new RouteAttribute(restPath.Path, restPath.AllowedVerbs)
{
Priority = restPath.Priority,
Summary = restPath.Summary,
Notes = restPath.Notes,
});
}
//Sync the RestPaths collections
appHost.RestPaths.Clear();
appHost.RestPaths.AddRange(RestPathMap.Values.SelectMany(x => x));
appHost.Metadata.AfterInit();
}
solution directions
Is there a way i could override the route finding? like extending RestHandler.FindMatchingRestPath(httpMethod, pathInfo, out contentType);
Or could i restart the path compilation/caching? (would be enough for now that the service would be reachable tenant wide )
All configuration in ServiceStack should be contained within AppHost.Configure() and remain immutable thereafter. It's not ThreadSafe to modify ServiceStack's Static Configuration at runtime like trying to modify registered routes or Service Metadata which needs to be registered once at StartUp in AppHost.Configure().
It looks as though you'll need to re-architect your solution so all Routes are registered on Startup. If it helps Plugins can implement IPreInitPlugin and IPostInitPlugin interfaces to execute custom logic before and after Plugins are registered. They can also register a appHost.AfterInitCallbacks to register custom logic after ServiceStack's AppHost has been initialized.
Not sure if it's applicable but at runtime you can "hi-jack Requests" in ServiceStack by registering a RawHttpHandler or a PreRequestFilter, e.g:
appHost.RawHttpHandlers.Add(httpReq =>
MyShouldHandleThisRoute(httpReq.PathInfo)
? new CustomActionHandler((req, res) => {
//Handle Route
});
: null);
Simple answer seems to be, no. The framework wasn't build to be a run-time plugable system.
You will have to make this architecture yourself on top of ServiceStack.
Routing solution
To make it route to these run-time loaded services/routes it is needed to make your own implementation.
The ServiceStack.HttpHandlerFactory checks if a route exist (one that is registered on init). so here is where you will have to start extending. The method GetHandlerForPathInfo checks if it can find the (service)route and otherwise return a NotFoundHandler or StaticFileHandler.
My solution consists of the following code:
string contentType;
var restPath = RestHandler.FindMatchingRestPath(httpMethod, pathInfo, out contentType);
//Added part
if (restPath == null)
restPath = AppHost.Instance.FindPluginServiceForRoute(httpMethod, pathInfo);
//End added part
if (restPath != null)
return new RestHandler { RestPath = restPath, RequestName = restPath.RequestType.GetOperationName(), ResponseContentType = contentType };
technically speaking IAppHost.IServiceRoutes should be the one doing the routing. Probably in the future this will be extensible.
Resolving services
The second problem is resolving the services. After the route has been found and the right Message/Dto Type has been resolved. The IAppHost.ServiceController will attempt to find the right service and make it execute the message.
This class also has init functions which are called on startup to reflect all the services in servicestack. I didn't found a work around yet, but ill by working on it to make it possible in ServiceStack coming weeks.
Current version on nuget its not possible to make it work. I added some extensibility in servicestack to make it +- possible.
Ioc Solution out of the box
For ioc ServiceStack.Funq gives us a solution. Funq allows making child containers where you can register your ioc on. On resolve a child container will, if it can't resolve the interface, ask its parent to resolve it.
Container.CreateChildContainer()

How to inject HttpRequestBase and HttpContextBase in Funq (while using ServiceStack)

I have been happily using AutoFaq for a couple of years and take advantage of its ability to easily inject HttpRequestBase and HttpContextBase in the MVC pipeline. This makes mocking and decoupling a lot easier.
I am in the process of changing my data layer to ServiceStack and as part of wiring the default Funq DI mechanism to my different layers I can't figure out how to inject HttpRequestBase and HttpContextBase.
Is there a way to do this? I am looking for the container.Register() analog inside of AppHost.Configure(Func.Container container).
Thanks
ServiceStack doesn't allow registering runtime dependencies with its IOC, although as ServiceStack Services and Request pipeline only binds to the IRequest interface which can just inject a mocked IRequest directly on the service when its required, e.g:
var service = new MyService {
Request = new MockHttpRequest()
};
var response = service.Get(new MyRequest { Id = 1 });
The Testing wiki shows other ways of testing ServiceStack services.
ServiceStack has it's own abstraction of the HttpContext and Request/Response. In v3.x, these are IRequestContext, IHttpRequest, IHttpResponse. This is to be implementation-independent of ASP.NET (console or Mono). It is recommended you use the abstractions instead of trying to use the underlying ASP.NET objects.
In your Service code, you may access them this way:
var httpReq = base.RequestContext.Get<IHttpRequest>();
var httpResp = base.RequestContext.Get<IHttpResponse>();
If you really need the real ASP.NET HttpContext, apparently you should be able to access it at IRequest.OriginalRequest. But if you are trying it the ServiceStack way, "don't do that".
More explanation of the Funq usage in v3 is here:
https://github.com/ServiceStackV3/ServiceStackV3/wiki/The-IoC-container

ServiceStack message queue handling and Profiler

I'm currently trying out the persistent mini profiler feature of ServiceStack and I'm currently having trouble registering profile information for my Redis Message Queue handlers.
A bit more background:
I have some regular REST api handlers which takes in a request, defers some updates of account information and replies OK back to the caller. These messages are posted to a Redis server, using the ServiceStack Redis MQ pattern. Therefore, the Redis message handling is registered as:
var redisFactory = new PooledRedisClientManager(redisClients);
var mqHost = new RedisMqServer(redisFactory, retryCount: 2);
var defaultThreadCount = 4;
mqHost.RegisterHandler<SomeDto>(m => this.ServiceController.ExecuteMessage(m), noOfThreads:defaultThreadCount);
mqHost.RegisterHandler<SomeOtherDto>(m => this.ServiceController.ExecuteMessage(m), noOfThreads:defaultThreadCount);
mqHost.Start();
And my messages are being handled properly too.
In a custom ServiceRunner I've enabled profiling of all requests in the BeforeEachRequest and added a custom Profiler step like this:
public override void BeforeEachRequest(IRequest requestContext, T request)
{
Profiler.Start();
using (Profiler.StepStatic("Executing handler"))
{
base.BeforeEachRequest(requestContext, request);
}
}
All my HTTP REST requests are making it to the SQL tables, but none of the MQ handler calls are registered. And I'm 100% confident that the handlers are indeed being executed, since the result of that execution is stored in a MongoDB collection.
Anything I'm missing?
-- EDIT --
I forgot to mention that this project is indeed hosted via an ASP.NET application. The AppHost is initialized in Global.asax App_Start - I just found it more convenient to have "before request" handing in a custom service runner rather than the ASP.NET Begin_Request handler.
I have a similar problem with a self hosted server. The problem is that the profiler uses HttpContext.Current to store the profiling results. If there is no valid context it does not know which profiling 'session' to add the results to.
It is possible to implement your own ProfilingProvider by setting Profile.Settings.ProfilingProvider, but, unless I am missing something, it will be tricky (if not impossible) to implement this properly in an Async environment with the current IProfilerProvider interface.
I wrote a very simple and naive provider which you can use for profiling. This will not pick up any of the steps that ServiceStack already adds by default, but it might still be useful for your own debugging.
Example use:
Profiler.Settings.ProfilerProvider = RequestProfilerProvider.Instance;
PreRequestFilters.Add((req, res) => RequestProfiler.Start(req));
GlobalRequestFilters.Add((req, res, dto) => {
var profiler = RequestProfiler.GetProfiler(req);
using (profiler.Step("Very slow step")) {
Thread.Sleep(1000);
}
});
GlobalResponseFilters.Add((req, res, dto) => RequestProfiler.Stop(req));

Configuring lifetime scopes in autofac when used as ServiceStack's IoC

I'm currently using AutoFac as the DI container for our ServiceStack web services app. I'm able to configure the wiring and everything, but after reading the section on Scopes, I'm at a loss at which scope would be best to use when registering my components. In our particular case, I think a PerHttpRequest scope would be OK since (please correct me if im wrong) I would want to dispose the dependencies as soon as the request ends.
My question is, how do I set this up in the container? I can't seem to find the "PerHttpRequest" lifetime scope within the included methods in autofac. I'm also unsure if ServiceStack does some kind of automagic to do this for me behind the scenes.
I'm using Autofac 3.0.1 on ServiceStack 3.9.35 on .Net 4 (running as a regular ASP host, not MVC). I'm also using the class described here as the IContainer adapter.
I wanted to avoid the overhead of the dependency on MVC, so the first answer didn't quite work for me.
Instead I used Funq to register a PerRequest ILifetimeScope, and resolve the ILifetimeScope in the ConatinerAdaptor before resolving the dependency.
public class AutofacLifetimeScopeIocAdapter : IContainerAdapter
{
private readonly Container _requestContainer;
public AutofacLifetimeScopeIocAdapter(Funq.Container requestContainer)
{
_requestContainer = requestContainer;
}
public T Resolve<T>()
{
var currentContainer = _requestContainer.Resolve<ILifetimeScope>();
return currentContainer.Resolve<T>();
}
public T TryResolve<T>()
{
var currentContainer = _requestContainer.Resolve<ILifetimeScope>();
T result;
if (currentContainer.TryResolve<T>(out result))
{
return result;
}
return default(T);
}
}
Then initialise with this
_autofacContainerRoot = builder.Build();
IContainerAdapter adapter = new AutofacLifetimeScopeIocAdapter(container);
container.Register<ILifetimeScope>((c) => _autofacContainerRoot.BeginLifetimeScope())
.ReusedWithin(ReuseScope.Request);
container.Adapter = adapter;
Then cleanup with
public override void OnEndRequest()
{
var currentContainer = _container.Resolve<ILifetimeScope>();
currentContainer.Dispose();
base.OnEndRequest();
}
This seems to behave as required for Autofac - SingleInstance, InstancePerDependency, and now InstancePerLifetimeScope which is perRequest.
Mythz response on the HostContext.Instance.Items collection can likely be used to remove the need for the
var currentContainer = _container.Resolve<ILifetimeScope>();
resolution, which should improve performance.
I think I have figured out how to make this work (using Autofac 2.6, which I am stuck on right now.) It involves using the following adapter and the Autofac.Mvc3 package:
public class AutofacIocAdapter : IContainerAdapter
{
private readonly IContainer _autofacRootContainer;
private readonly Container _funqContainer;
public AutofacIocAdapter(IContainer autofacRootContainer, Container funqContainer)
{
// Register a RequestLifetimeScopeProvider (from Autofac.Integration.Mvc) with Funq
var lifetimeScopeProvider = new RequestLifetimeScopeProvider(autofacRootContainer,null);
funqContainer.Register<ILifetimeScopeProvider>(x => lifetimeScopeProvider);
// Store the autofac application (root) container, and the funq container for later use
_autofacRootContainer = autofacRootContainer;
_funqContainer = funqContainer;
}
public T Resolve<T>()
{
return ActiveScope.Resolve<T>();
}
public T TryResolve<T>()
{
T result;
if (ActiveScope.TryResolve(out result))
{
return result;
}
return default(T);
}
private ILifetimeScope ActiveScope
{
get
{
// If there is an active HttpContext, retrieve the lifetime scope by resolving
// the ILifetimeScopeProvider from Funq. Otherwise, use the application (root) container.
return HttpContext.Current == null
? _autofacRootContainer
: _funqContainer.Resolve<ILifetimeScopeProvider>().GetLifetimeScope();
}
}
}
Steps to implement:
Add the Autofac.Mvc3 NuGet package to your web project (NOTE: does
not matter that your project isn't using MVC. The solution might be slightly different with Autofac 3, which cannot use Mvc3 integration.)
Follow the ServiceStack IoC page in hooking up a custom IContainerAdapter
for Autofac, using the following implementation
Note the RequestScope in ServiceStack's IOC only refers to ServiceStack's built-in Funq IOC.
To use RequestScope in another IOC Container like AutoFac you generally need to notify AutoFac at the end of the request so it can clean up all its request-scoped instances. To do this, ServiceStack provides the AppHostBase.OnEndRequest() hook you can override to get execute custom logic at the end of each request.
I'm not familiar with how AutoFac's custom lifetime scope works but more details about it can be found in:
AutoFac's InstanceScope wiki page
Primer on AutoFac's Lifetime scopes
Answer on how to manage AutoFac' request scope in MVC
Other info that might be useful for managing instances in ServiceStack is that every instance in put in the HostContext.Instance.Items dictionary or disposable added to HostContext.Instance.TrackDisposable are automatically disposed at the end of each request.
Update 2015-11-25: I changed the implementation by using global request and response filters. I put both ServiceStack V3 and V4 solutions into this repository and both versions are available as nuget packages.
I solved this problem by opening a new scope in Application_BeginRequest and disposing in Application_EndRequest. In the container adapter I check if this scope exists and use it, if not, I use the container. This allows using .InstancePerRequest() registration scope.
Described with gists here.

Resources