Are Services Requests supposed to be Actors or Commands?

hays.clark's Avatar

hays.clark

28 May, 2013 10:00 PM

I have been looking at many of the RBL Service examples and I'm a bit confused as to the best practice for Services. I fully understand that the goal is to separate the models 'storage' responsibility from the 'services' communicating responsibilities. I find examples like the Twitter example where a Service has event listeners; however, there is also Shaun Smith's advice from that 'You definitely don't want Services or Models listening for events.'

I have two options at this point for the 'requests':
Each request type is an Actor: ( class GetUserPictureService extends Actor implements IGetUserPicture ). Very similar to almost all of the RBL example of services I have found. The main advantage seems to be a single place to stash data about other requests which is more complicated if you use Command. In addition the service persists for the entire duration of the application.
RBL Example:
http://joelhooks.com/2011/03/12/an-introduction-to-robotlegs-as3-part-3-services/

Option 2 is making a Command: ( class GetUserPictureServiceCommand extends Command implements IGetUserPicture )
Each request becomes a new command object which often seems to require using Statics to deal with multiple requests. In addition if a Command fails it's not always clears who is listening or cares if the command fails. This method seems to be recommended in this post: http://knowledge.robotlegs.org/discussions/questions/136-command-invoking-functions-in-service, and also in the RBL book.

Is there a clear winner? I am leaning towards the Actor style right now.

Thanks in advance.

  1. 1 Posted by Jerome Maurey-D... on 29 May, 2013 03:28 AM

    Jerome Maurey-Delaunay's Avatar

    Hi,

    I usually have my services as Actors, mostly because they are persistent and often used parts of the apps. They also are great source of leaks! Especially when dealing with external, unmanaged data. So pre-allocation and avoiding costly GC is also a win for Actors.

    I build commands to be fast and disposable. They usually only deal with application logic. Like responding to a service event or dispatching events to update view and actors. Embedding complex systems, like service calls and results processing from an API call feels couter intuitive inside a Command. That command can just query the results from the last service call and get sanitized data, ready for the app's other actors to use.

    I feel MVCS views and services can be recycled. But, in most cases, services will port even better than most views! So I would keep services as Actors to frame them better. Commands (and some views) are mostly specific to the app you build.

    I almost always port over my AssetsService that handles asset logic from an external XML file and an associated AssetLoaderService. These are battle tested and therefore reused as needed.

    Recently I had a service handle Stage3D and specifically the wiring of Away3D with Starling+Fearthers. Again, something I can port over many projects and keep improving upon.

    I am sure there are others that might have different views on how to segment apps, tho.

    Cheers,

    J.

  2. Support Staff 2 Posted by creynders on 29 May, 2013 07:24 AM

    creynders's Avatar

    (Re-posting my comment here, from duplicate thread)

    which was specificlly discourages in the example link bellow.

    No, the other example discourages letting service classes listen to system events. Services are allowed to listen to events dispatched by the class they're wrapping.

    What you see as 2 options is actually one. Best practice is to map a command to a (system) event, let it call a service method, which in turn creates the necessary helper(s) (URLLoader or Externalinterface or...) The service listens to events coming from the helper instances and then, when finished, dispatches a concrete system event which is mapped to a command handling the results.

    Concurrent/parallel service requests is something I tend to handle in my service classes. Sometimes they're allowed sometimes not. Depending on that I let the service handle the multiple method calls differently.

  3. 3 Posted by hays.clark on 29 May, 2013 06:47 PM

    hays.clark's Avatar

    @creynders,
    Thank you for clarifying what Shaun was stating in his comment. With that quote out of the picture the concept is much more solid in my mind. I was familiar with what Shaun is refering too, I always try to remember Joel's 'dinner party' quote:

    "Models and services are like the worst kind of dinner party guest. They have no interest in what other people have to say."
    -ActionScript Developer's Guide to Robotlegs

    @Jerome
    Thanks for your input as well. You have an excellent point about GC which I have completely overlooked. My current project is not very chatty with the server; however, if I were to use my current Command based service layer on a more chatty application that could cause a lot of unintended GC execution. In addition, I don't like the 'static' variables I have hard to utilize.

    I also follow what you are saying about pulling your wrappers from project to project. While somewhat off topic, I personally I have been considering my wrappers for Starling, the Stage or Security as Models because they are not asynchronous. Again I am just following Joel advice on this:

    "Does your class dispatch state/status update events:
     - Only synchronously, immediately following a call on its API—in which case it’s a model
     - Asynchronously (usually initially triggered by a call on its API but perhaps sometime later)—in which case it’s a service"
    - ActionScript Developer's Guide to Robotlegs (p. 50)

    I really don't have a hardened opinion about the Service layer as it seems to be less documented compared to MVC. MVC is much easier to research and find and compare the variations that exists: IE, RBL vs Apple's implementation, etc etc.

    For me it looks like an Actor based service is the right way to go in this case. But I could see a Service call that is executed once for initial setup being a Command.

  4. Support Staff 4 Posted by creynders on 30 May, 2013 10:41 AM

    creynders's Avatar

    For me it looks like an Actor based service is the right way to go in this case. But I could see a Service call that is executed once for initial setup being a Command.

    You should avoid putting any real "work" in commands. They're simply the "glue" in between system parts, they translate system messages (events) to service calls. A bit like mediators do for views. If you have a service which is executed only once, then destroy it after it has done it's job. Again, this is for reusability reasons.
    Commands are tightly coupled to the framework and application context, they access all kinds of RL-specific and system-specific parts, which severely limit their reusability.
    Services on the other hand can be lifted out of one project to another, even if the new project doesn't use RL. (Even if it uses Inject-tags, it's not a problem, since they don't raise any errors when used in a non-RL project, they are simply stripped by the compiler)

    If you answer 'yes' to one or more of the following questions, I recommend a service:

    • Is it an async operation?
    • Does it "do" anything outside your application (communicates with the execution environment, loads data from a URL, etc.)?
    • Should it be reusable?
    • Does it wrap a 3rd party library?
  5. Support Staff 5 Posted by Ondina D.F. on 10 Jun, 2013 11:44 AM

    Ondina D.F.'s Avatar

    Hi Hays,

    I guess everything is clear now, right? I’m going to close the discussion, but feel free to re-open it, if need be.

  6. Ondina D.F. closed this discussion on 10 Jun, 2013 11:44 AM.

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