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 ... 6 7 [8] 9 10
 71 
 on: July 02, 2015, 09:27:10  
Started by saad - Last post by saad
Hi Cliff,

Trying to get my head around implementing a plumbed multicore app with Java Servlets, wondering if there's an implementation or if you can please guide for startup mechanics. I see Servlet as Front Controller/Router intercepting requests and delegating on to PureMVC apparatus via it's Mediator. I've following steps under review.

1. Define a class implementing ServletContextListener that loads with the application server, instantiate Shell and other modules inside contextInitialized method, and plumb them followed by shell and module registration with the Servlet Context so references are available to Servlets in #2

2. Servlets are lazily instantiated and are available after ServletContext is constructed. Within each servlet's init method get reference to custom ServletContext, then reference to Shell or Modules and using a method like acceptRouter along with acceptInputPipe/acceptOutputPipe while passing this so a RouterMediator can be set upon it.

Any thoughts?

 72 
 on: June 24, 2015, 07:34:11  
Started by saad - Last post by puremvc
Hey Saad,

Glad to hear the refactor worked out for you. It's always nice when you can chop a few heads off the complexity beast :)

Cheers,
-=Cliff>

 73 
 on: June 23, 2015, 01:27:56  
Started by saad - Last post by saad
Hi Cliff,

It's awesome and much better now. Took the Formal Request route, not only the modules are compact now but actors are thin and manageable as well.

Using a SimpleCommand and a Proxy, although the environment is node.js but adopted few things from Flex paradigms, for instance common.DatabaseObject (RemoteObject in Flex) which itself now is a highly reusable actor across all modules, accepts the QueryRequest/Observer (sql + values + request/response objects), returns the token on which Proxy sets itself as a Responder. DatabaseObject then pools the connection, executes the SQL and returns result/fault via token.responder to the Proxy.

Model got reduced to a single proxy that just populates the sql string and values array of QueryRequest, and notifies the command on result/fault. Further View tier (Router) is handling result decoration as per the REST specs for the client.

Thanks a lot for your great support.

 74 
 on: June 16, 2015, 12:35:59  
Started by saad - Last post by puremvc
Still, you could implement the formal request and use SimpleCommand and Proxy. The Proxy classes could possibly be simplified intto a single, more generic one by having the Request class determine the HTTP method GET/POST/PUT/DELETE and the URL base, but you supply the final node like :id in the constructor.

Then as I mentioned before,
The command would then trigger different notifications based on the response it gets back, which might mean a Command and/or Mediators answer, that end of things - handling of the result - will vary based on your app.

-=Cliff>

 75 
 on: June 15, 2015, 05:28:51  
Started by saad - Last post by saad
Hi Cliff,

I apologize for not been able to respond earlier as I've been completely slammed, but I read the response, been pondering, also looked up the book reference and I understand the points mentioned here too, but here's something which led to this structure and I'd explain more with the help of your quote.

It would need a method for each of list/detail/insert/update/delete, but its handling of the response would be similar.

It's basically the handling of the response that's different for each of the actors. for instance.

  • GET /products -> 200 OK [] (Array)
  • GET /products/:id -> 200 OK {} (Object) or 404 Not Found
  • POST -> 201 Created
  • PUT /products/:id -> 200 OK or 204 No Content
  • Delete /products/:id -> 200 OK or 204 No Content

And there's more to the REST specifications not covered here, for instance content negotiation factors or decorating the result with the link of the newly created resource in the response headers for POST commands.

So it's very different, unique and detailed post-async or post result/fault responsibilities for each kind of request that are the reasons behind separate AsyncProxies with their dedicated roles.

Initially I did combine 1) List and 2) Detail and tried with a single actor but due to async nature of node.js itself (callback for everything) it was turning into a Fat proxy and from there I split up things and assigned single responsibility/role to each actor.

SideNote:

With reference to AsyncCommand, PureMVC book referred to it as
muddle the responsibilities of the Command, making it implicitly involved in the persistence mechanism by implementing Responder and handling ResultEvents and FaultEvents

I agree and I could have Proxy send notifications (RESULT/FAULT) after result decoration but it's because of the nature of node.js and following simplicity measures that employed AsyncCommand.

node.js runs under a single process (shared/single memory space for all users) and in order to serve multiple users, a new instance of proxy has to be created for each request in a command, i.e. no registration of proxies in StartupCommand, since all actions within the proxy are async so a single instance can't be used for another request while it's asyncAction is in progress.

Then for it to be able to send notifications for result/fault it needed facade registration with a unique name (Proxy.NAME + request.id) and then has to be removed at the end to release memory, so a dedicated command was required for that. I could create another method within the proxy that remove itself from facade at the end, but then re-using the same command that instantiated it seemed more intuitive for removal, so that's how a dedicated pair concept came into existence.

Later on, I simplified things, for each request a new AsyncProxy instance gets instantiated but without repeatable facade registrations and removals, it performs it's asyncActions, parses results, decorates it, and then it responds back to it's paired AsyncCommand for sending notification. AsyncCommand frees up a bit from having to register and remove proxies from facade. By handling result parsing/decoration within the AsyncProxy and responding to AsyncCommand for notification only, I hope that avoids the muddle while also keeping the AsyncCommands thin.

So in summary, each request fires it's notification, for which Controller instantiates a new Command, and that command in turns instantiates a new proxy, calls asyncAction on it, the proxy then pools the connection, executes the SQL, decorates the results first within it's own result/fault handler, and then responds back to the Command for RESULT/FAULT notifications. All of this is happening in parallel/sequence for all the requests. These new instances of AsyncCommand/AsyncProxy pairs for each request is basically making it possible to serve several different user requests under a single process environment but then at the same time exploding the module.

 76 
 on: June 09, 2015, 01:46:48  
Started by saad - Last post by puremvc
Hi Saad,

I agree with your precepts for decomposition of actors and modules. However, I think the explosion of classes in your current design is probably due to the literal mapping of your application's actors to the REST interface you are exposing to the client.

For instance, having a separate command and proxy pair for list/detail/insert/update/delete seems a bit excessive. Usually I have one Proxy for a data source and perform all operations from it. A single command could look at the incoming request and determine which methods to call on the Proxy.

I see you're using AsyncCommand/AsyncProxy. Not my favorite implementation. I like the "Formal Request" architecture (which I describe in the Advanced Model Topics section of the PureMVC book) better.

The essence of that architecture is having a "Request" object which is submitted to a Proxy, via a method like MyProxy.submitRequest( request:IRequest ). That request tells it the operation the caller (usually an ICommand) wishes to invoke. And it also has a callback function (courtesy of extending PureMVC Observer) that lets the result come back asynchronously to the caller. This will work with a SimpleCommand and Proxy.

I described the basic premise in code here:
http://forums.puremvc.org/index.php?topic=1955.msg8724#msg8724

You'd want a more advanced request that could have a type and other parameters probably. That example just triggers a static call and gets the result back. It also uses AsyncToken (a Flex-ism) that ensures the Proxy gets the result of the call. Whatever methodology you're using in JS in your AsyncProxy would be used there. It has nothing to do with the communication between the command and the proxy.

I'm willing to bet you could have a single command figure out the type of request to generate, then submit it to a single proxy to get the work done and return the result. Your router would simply need to send the right notification to the command containing the information about the REST path, so that the Command could determine the appropriate request type to create. With a single submitRequest() method on the Proxy, it would mean you don't have a big switch in that Command calling different Proxy methods, so it shouldn't be very large. Nor should the Proxy really. It would need a method for each of list/detail/insert/update/delete, but its handling of the response would be similar.

The command would then trigger different notifications based on the response it gets back, which might mean a Command and/or Mediators answer, that end of things - handling of the result - will vary based on your app. But the collapsing of the commands for initiating a call into one, and the collapsing of the separate proxies for every kind of call by way of the formal request object with built-in callback should get this under control without pushing too hard at the upper limits of your #1 decomposition rule.

 77 
 on: June 08, 2015, 04:02:00  
Started by saad - Last post by saad
I've recognized following patterns while working with PureMVC and also enforced some rules on top of that in my projects.

  • Actors have very focused responsibilities
  • Modules have very focused goals

For #1, besides design I also determine by Lines of Code, an average is 65-125 LOC, anything goes beyond is a sign that design needs revision and usually gets solved by brining in another reusable actor.

For #2, If there are too many actors and module is getting bulky, that means the module needs further decomposition, therefore it gets split into another reusable module. On an average usually 3-5 Actors/Commands per module.

Under REST application I'm finding #2 hard to implement as there are too many operations just for a single entity, ending up with 9 Commands in this case. I reduced the clutter at least for the eye by moving the crud based operations into a separate folder (crud) for each module and here's the diagram. (9 Commands in red)

 78 
 on: June 08, 2015, 06:35:50  
Started by saad - Last post by puremvc
Hi Saad,

I know all this makes sense to you within the context of the work you've done. But if you could draw us a diagram of the modules and their message flow as well as a diagrams of the individual modules, it would make things a lot clearer.

Cheers,
-=Cliff>

 79 
 on: June 06, 2015, 10:03:04  
Started by saad - Last post by saad
In context of a REST based server multicore app (node.js, express.js), the application under progress is getting bulky and complex because of too many operations involved within each module and since all these operations are related to this single entity (database entity) it doesn't feel intuitive to split them out into several submodules, (besides I've several modules already for other entities).

Starting with 4 CRUD operations (GET, POST, PUT, DELETE), for each there's an AsyncCommand with it's associated AsyncProxy. Adding PATCH support will add another couple.

On top of that some modules may require file upload, although the operation is redirected right from the RouterMediator and piped towards S3Module (Amazon S3 file storage) but then the sender module itself will require S3ResultCommand to handle results (4 kinds of results), or in other words every other module supports different actions/names and therefore requires a Command to handle those results.

Any additional requirement may force another couple of Async Command/Proxy into the module.

Every CRUD AsyncCommand (triggered from the view/RouterMediator/Router), triggers asyncAction of it's associated AsyncProxy, that pools the connection, gathers params from the body, headers, queryString etc., executes SQL, calls the the result/fault within the Proxy, releases the connection there and then responds back to the AsyncCommand so it could shuttle the results to the View layer (browser output).

So even combing above operations into fewer actors will make those actors bulky, plus there could be content negotiations factors that would require me to have different SQL calls in each actor, so I'd rather keep actors following SingleResponsibility Principle.

No problem with the View Layer though, it's pretty lightweight, a single actor ResponderMediator just listens for two notifications (RESULT/FAULT) fired from each AsyncCommands which it then outputs to the browser via Responder component.

In essence REST requirements involving several operations around each entity/resource is requiring me to have several commands and proxies for the related module and I'm not finding a way out of it.

 80 
 on: May 26, 2015, 01:30:35  
Started by saad - Last post by saad
1) Pipes
https://www.npmjs.com/package/npmvc-util-pipes

2) AsyncProxy
https://www.npmjs.com/package/npmvc-util-asyncproxy

3) AsyncCommand
https://www.npmjs.com/package/npmvc-util-asynccommand


Kudos to Robbert Streng - https://www.npmjs.com/package/npmvc

Pages: 1 ... 6 7 [8] 9 10