Signals and Garbage Collection

Tyler Padley's Avatar

Tyler Padley

24 May, 2013 03:41 AM

I have a bit of an issue and I'm wondering if I'm thinking about it the right way here...

first I map my service

injector.mapClass(serviceClass);

then, in a signal command, I dynamically map the expected result command

signalMap.mapSignalClass(resultClass, commandClass, true);

then create the service

service = injector.getInstance(serviceClass);

call the method

service.load();

inside the service is an injection mapping for resultClass that should be satisfied by signalCommandMap and it should be called upon completion of the service call, but it never makes it to resultCommand as it is being Garbage collected.

What I am looking for is a way to re-use a service but dynamically re-route the result signal to different commands prior to calling the service method. Is this possible?

if I mapped the service as a singleton with a singleton injection signal, would calling the signalCommandMap before calling the service method override the signal? I didn't think it would since it had already been injected into the service by that point.

Any help / suggestions welcome.

  1. 1 Posted by Tyler Padley on 24 May, 2013 02:37 PM

    Tyler Padley's Avatar

    I was able to get what I was after using commandMap.detain and commandMap.release, but this implementation doesn't feel clean to me. Is there any way to make a "mapClass" instance persist until the results of an async call are returned?

  2. Support Staff 2 Posted by creynders on 24 May, 2013 04:52 PM

    creynders's Avatar

    In my experience this is a warning your service class should actually be split up into several service classes (but, granted, not always). Is this a generic, "base" service class? Or is this a really concrete service class with a single responsibility and specific to one service call? And why exactly should the response be rerouted to several commands, i.e. what happens with the results?

  3. 3 Posted by Tyler Padley on 24 May, 2013 05:09 PM

    Tyler Padley's Avatar

    The service class in question is a generic XML loader routed through HTTPService. I want it to remain a mapped class rather than a singleton because they should be able to operate independently and from different locations within our framework. However, the converting of the XML results into VO's should be handled within command logic and I'd need different command logic for different requests. I shouldn't have to make a custom signal for each request.

  4. Support Staff 4 Posted by creynders on 26 May, 2013 05:55 PM

    creynders's Avatar

    I tend to create concrete service classes that use an injected base service instance. This allows me to leave the creation of the result signals to the specific concrete service classes.

    In case you don't want to do that you could pass a result signal instance as a payload to the request signal, catch it in the service instance and let it dispatch the results.

    If you really don't want to create a custom signal for each request ... ummmmm ... then you'll need to create some kind of command that checks a value in the service which uniquely identifies the request and use some kind of switch-case to call the appropriate commands. I would recommend against this solution though. I'd definitely go for the dedicated signals. (Or use events, I only use signals for coupled communication, not system-wide)

  5. 5 Posted by Tyler Padley on 27 May, 2013 12:36 AM

    Tyler Padley's Avatar

    Thanks creynders, I did end up passing an optional result and fault signal into the method. This has allowed me to do the command mapping from within the command that handles the request, which I feel is cleaner separation, however I would like to have been able to do it without persisting the command or the service class...

    I was trying to figure out a way to have my concrete service instance live through an async call while still being injected via mapClass.... but the garbage collection is too quick. Persisting the command resolved this issue, I just have to add a secondary callback to release the command upon completion of service invocation, which I feel should be left to the service itself, but I don't know of a way to have the service be both entirely self-contained and persist past async... I guess that's not a robotlegs problem, more of an actionscript problem, though I'm researching AsyncToken or the robotlegs Oil extension as a means of prolonging the life of my service.

  6. Support Staff 6 Posted by creynders on 27 May, 2013 07:05 AM

    creynders's Avatar

    I think the easiest solution would be to use a service caching class which implements the same interface as your service class. Map it as a singleton to the injector and let it create and store the service instances. When a service finishes its job, it removes the service instance from the cache.
    Inject the service cache instead of the service class instance into the commands.

    Also, maybe you'll be interested in my SignalResponder. It basically wraps 4 signals: start, result, fault and progress. It provides default signals (but you can overwrite them), uses lazy initialization, et cetera. I.e. it takes care of a number of boring things to deal with async results through Signals.

  7. 7 Posted by Tyler Padley on 27 May, 2013 12:50 PM

    Tyler Padley's Avatar

    Sure that does look interesting, and could be applied to other types of loading services. I'll be sure to check it out.

    Thanks

  8. Ondina D.F. closed this discussion on 04 Jun, 2013 04:53 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac