Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Targeting for proxie result  (Read 9456 times)
Orion
Newbie
*
Posts: 6


View Profile Email
« on: April 24, 2009, 02:32:19 »

I have proxie class wihch load binary data from server. It's look like image downloader. Some parts of my application ask proxie to load some resources:

PersonalCardMediator.as

listNotificationInterests() : Array
{
   return [ ImageProxy.RESOURCE_LOADED ];
}

handleNotification( note : INotification ) : void
{
   switch ( note.getName() )
   {
      case ImageProxy.RESOURCE_LOADED:
      {
         if( firstUID == note.getBody().UID )
            ...
}

getImage()
{
   imageProxy.getResource( firstUID );
}

---------------------------

MainWindowMediator.as

listNotificationInterests() : Array
{
   return [ ImageProxy.RESOURCE_LOADED ];
}

handleNotification( note : INotification ) : void
{
   switch ( note.getName() )
   {
      case ImageProxy.RESOURCE_LOADED:
      {
         var UID = note.getBody().UID;
         if( secondUID == UID || thirdUID == UID || ... )
            ...
}

getListImages()
{
   imageProxy.getResource( secondUID );
   imageProxy.getResource( thirdUID );
   ....
   imageProxy.getResource( zUID );
}

and more
---------------------------

Problem is: If I send notify when complete load each resource, all my subscribed components must check, is needed resource or not. How I can optimize this?
Sorry for my English.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: May 12, 2009, 05:36:13 »

Use the AsyncToken pattern.

Have the Mediators subscribe to a unique notification string like ImageProxy.RESOURCE_LOADED+"/"+PersonalCardMediator.NAME

:
override public function listNotificationInterests():Array
{
   return [ImageProxy.RESOURCE_LOADED+"/"+PersonalCardMediator.NAME]
}

Then have the Mediator pass its name to the Proxy request, and have the Proxy set the name as a dynamic property of the token that is returned when it makes the service call like:

:
private var token:AsyncToken;
...

public var callService(mediatorName:String):void
{
   token = service.send();
   token.mediatorName = mediatorName;
}

When the result comes back, then send an ImageProxy.RESOURCE_LOADED+"/"+token.mediatorName notification.

:
public var onResult(event:ResultEvent):void
{
   token = event.token;
   setData(event.result);
   sendNotification(RESOURCE_LOADED+"/"+token.mediatorName, data);
}

The mediator that made the call will get the result directly.

-=Cliff>
Logged
Orion
Newbie
*
Posts: 6


View Profile Email
« Reply #2 on: January 22, 2010, 03:46:25 »

The same question. What is the best way for modular application.
Example. I have module and core with some proxy.

My module have some mediators working as previous example:

PersonalCardMediator.as

listNotificationInterests() : Array
{
    return [ImageProxy.RESOURCE_LOADED+"/"+PersonalCardMediator.NAME]
}

override public function onRegister() : void
{
   sendNotification( AppFacade.LOAD_RES, { resourceID : resourceID, recepientName : NAME} );
}

in JunctionMediator:

handleNotification( note : INotification ) : void
{
   switch ( note.getName() )
   {
      case AppFacade.LOAD_RES:
      {
         var message : Message = new Message( MessageNames.LOAD_RES, id: note.getBody().resourceID );
         junction.sendMessage( PipeNames.STDCORE, message );
      }
   }
}

when answer is recieved, how I know who recepent?

OK, actually I can send message with recepientID, and later send this attribute back. But I do not think that this is a good way. Because it's unnecessary information for Proxy.

Second way I can organize que in JuncationMediator:

...
case AppFacade.LOAD_RES:
      {
         if( myQue[ resourceID ] )
            myQue[ resourceID ] = [];
         myQue[ resourceID ].push( recepientName );
         var message : Message = new Message( MessageNames.LOAD_RES, id: note.getBody().resourceID
      }
override public function handlePipeMessage( message : IPipeMessage ) : void
{
   var resourceID = ResourceVO(message.getBody).id;
   if ( myQue[ resourceID ] )
      sendNotification( [AppFacade.RESOURCE_LOADED+"/"+myQue[ resourceID ][0], message.getBody() );
}

But in this way I store "myQue" in mediator, maybe it's not best place and I must create special Proxy for this data?
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: January 22, 2010, 11:12:54 »

OK, actually I can send message with recepientID, and later send this attribute back. But I do not think that this is a good way. Because it's unnecessary information for Proxy.
This is a perfectly good approach. How and where the recipient ID is placed, tracked and responded to are all optimizable variables, so if your first implementation seems rough, think of ways to tune it.  But the approach is tried and true in the real world.

For instance, a restaurant will often give you an order number (or they take down your name, or note what table you're at) and when your order is ready, they either call out your order number, (or name, or table) or the waiter or waitress brings it to the designated table.

There are lots of variations on the theme, which amounts to an async token. Your order is tied to this and follows its way *on the order* through the kitchen where it is prepared so that when it's done, there is a way of knowing which veggie burger goes to which customer.

An ID *is* necessary information in a modular async communications scenario. It may not be related to the actual data the 'order taking' proxy deals with, but it definitely needs to be retained. The chef may be focused on cooking great food, but if he can't keep track of the orders, the overall restaurant breaks down.

So, if you're interested in routing the incoming message back to the actor that called for it, then definitely tack an ID of some sort onto it and be prepared to handle that return based on the ID.

-=Cliff>
Logged
Orion
Newbie
*
Posts: 6


View Profile Email
« Reply #4 on: January 25, 2010, 12:51:16 »

Yes, if I interested in routing the message, some part must be available for all time message live cycle.
Some requests in my system is SOAP requests. It's look like

:
soap.createElement.addEventListener( SoapEvent.RESULT, resultHandler );
soap.createElement.addEventListener( SoapEvent.ERROR, errorHandler );
soap.createElement( rootID, typeID );

This part contained into core proxies. If module wants to get the query result, he send message:

ModuleJunctionMediator:

:
var message : MyMessage = new MyMessage( Places.SERVER, Operations.CREATE, Targets.ELEMENT, { rootID: 111, typeID: 222 } /*<----some untyped properties*/ );
junction.sendMessage( PipeNames.TO_CORE, message );

It's REST-like SQL-based message system :)

Now I confused how implement this:

"soap.createElement.addEventListener( SoapEvent.ERROR, errorHandler );" :)

I have two important chains:

                                      -> [ async req. result ] -> [ core to module message ]
[ module to core message ]
                                      -> [ async req. error ] -> [ core to module message ]

and some main task:
1. Detect "my message". Discuss in previous post "how track result"
2. Error messages it's look like "track result" but have some differences.

For my "answer message" I create message the same type:

CoreJunctionMediator:

:
var message : MyMessage = new MyMessage( Places.SERVER, Operations.CREATE, Targets.ELEMENT, { elementVO: elementVO } /*<----result of async req.*/ );
junction.sendMessage( PipeNames.TO_MODULE, message );

The first way, create new ErrorMessage class like:

var errorMessage : ErrorMessage = new ErrorMessage( Places.SERVER, Operations.CREATE, Targets.ELEMENT, "Error Message" );

Difficult for me, where the place to "truck implementation":
1. Create unique ID for all messages.
myMessage.UID,
errorMessage.UID and errorMessage.sourceMessageID = [ myMessage.UID ] <-- this message generate error. But this way cant use for track normal messages, because MyMessage haven't attribute recipientID;
And module must "memorize" each request.

2. Create not errorMessage.sourceMessageID, but errorMessage.sourceMessage

3. Create recepientID for MyMessage...

Actually I'm confused :)

Main q.

How create module-core-module communication with track source messages in answers and error messages for sync and async requests :)
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #5 on: January 25, 2010, 11:38:34 »

You had it at 3. Add the recipientID property to the MyMessage class.

Then, if you are using Flex or AIR, simply set a dynamic recipientID property on the asyncToken returned immediately by the service's send method. Then when the result or fault comes back the token.recipientID will be set to the value that was put on the token when you made the call. That goes back onto the message that gets sent back to the calling core regardless if its an error or success.

If you're not using Flex/AIR to handle these calls then you need to pass it as a request header property or to your service and have the service return it. That is implement your own server support for the AsyncToken pattern so that the recipientID stays with the request all the way through the loop.

-=Cliff>
Logged
Pages: [1]
Print