SSE and ReusedWithin

Hi Mythz,

Just to keep me on the right track here.
I am trying to track down a potentially multi-threading synchronicity problem we are having when our service is handling SSE events.

Our ServiceStack service has a internal class GlobalReceiver : ServerEventReceiver that handles SSE events from another service. Currently, these SSE events are coming in without authentication.

In our service, if we have a type that is registered in our AppHost.Configure() like so: container.Register<IMyType>(x => new MyType()).ReusedWithin(ReuseScope.Request) does a new instance of MyType actually get created when a new SSE event arrives? If not, what instance is used?

I just want to be sure we understand what is happening here.

thanks

Don’t use RequestScope, just use ReuseScope.None. There are known issues using async Requests and Request Scope in SmartThreadPool-based HttpListener hosts.

Did you mean?

“Don’t use ReuseScope.Request”???

Instead, use ReuseScope.None will create an instance every time its asked for??

Right, ReuseScope.None means don’t reuse instances. The SSE connection is a single long-lived HTTP Request, how are you resolving the dependency from within the SSE request? Not clear at which point the dependency is being resolved, is this in a SSE callback?

The dependency is being resolved in the GlobalReceiver.

So the question really is, how many times will that dependency be resolved if we use ReuseScope.None ??

Wait are you talking about the clients ServerEventReceiver to handle callbacks on the ServerEventsClient? The shouldn’t have anything to do with servers HTTP Request Context.

The lifetimes of the Receiver is determined by the ServerEventsClient.Resolver which by default uses the NewInstanceResolver where a new receiver instance is created to handle each event. You can change this to use a SingletonInstanceResolver and the same receiver instance will be used to handle the events.

You can also inject a Funq Container which will let you autowire dependencies. If using a new Funq Container each dependency you register can either have singleton scope (by default) or use ReuseScope.None to resolve transient instances.

Yes, I am talking about the client end, receiving events sent by another service.

I am doing this in my services’ AppHost.Configure() to setup a SSE client to receive SSE events from another service.

private void CreateServerEventsClient(Container container, IClientConfiguration configuration)
        {
            var baseUrl = configuration.SomebaseUrl;
            this.serverEventsClient = new ServerEventsClient(baseUrl,
                Channels.aChannel1,
                Channels.AChannel2);
            this.serverEventsClient.RegisterReceiver<GlobalReceiver>();

            container.RegisterAutoWiredTypes(this.serverEventsClient.ReceiverTypes);
            this.serverEventsClient.Resolver = container;

            this.serverEventsClient.Start();
        }

Where the passed in ‘Container’ parameter is the one passed to AppHost.Configure()

The intention is that the SSE client can use the same registered types that the service is using.

My question was, given that the SSE client is using the same registered types as the service within which it lives, for the types that declare ReuseScope.Request does that mean that when a new SSE event arrives, a new instance of the registered type is created by the container?

You should definitely not be using the servers Request Scope dependencies in any ServerEventClient handler, Request scoped dependencies are stored in the servers RequextContext, the lifetime of which is managed by the start/end of a HTTP Request executed on a HTTP Worker thread whereas the callback of a SSE client is executed on an async I/O callback thread. There’s no defined “RequestScope lifecycle” for SSE client handlers, use either singleton or transient scoped dependencies.

OK, thanks for the clarification.

I think something on the SSE client wiki page (https://github.com/ServiceStack/ServiceStack/wiki/C%23-Server-Events-Client) giving this advice with a code example, for when you want a SSE client in a ServiceStack service might be good guidance for others. It would help tie the two technologies together.