Asynchronous factories (scripting)

Next
 From:  pressure (PEER)
11087.1 
What should I know about asynchronous factories? From old forum posts it sounds like there were some complications around loose objects that have since been solved. Is there anything that I need to know now about async factories when using them in a script?

There's a function .waitForAsyncUpdate() associated with calcarea, calclength, and calcvolume. Does that have anything to do with "asynchronous factories", or is that a whole other kind of thing specific to just those 3 factories? It seems like "asynchronous factories" generate an objectList in the normal way, rather than filling in an input slot.

- Peer
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
11087.2 In reply to 11087.1 
Hi Peer,

re:
> From old forum posts it sounds like there were some complications around loose objects
> that have since been solved. Is there anything that I need to know now about async factories
> when using them in a script?

Yes there used to be an issue that the id of an object was generated when it was added to the geometry database. So if you used factory.calculate() to generate some geometry but never add it into the geometry database then it would not have an id value and ids are needed for factories that do async updates.

In v4 this was solved by generating object id values right when the object is initially created, so there isn't a situation anymore where an object doesn't have an id value set on it.


> There's a function .waitForAsyncUpdate() associated with calcarea, calclength, and calcvolume.
> Does that have anything to do with "asynchronous factories", or is that a whole other kind of
> thing specific to just those 3 factories?

The .waitForAsyncUpdate() function is part of the base geometry factory class so it can be used on any factory.

It's used internally by calcCurveLength(), calcSurfaceArea(), and calcSolidVolume() because these needed to return a number value, not an object list and so they use factory.update() followed by waitForAsyncUpdate() because factory.update() can also transmit back modified input values.


> It seems like "asynchronous factories" generate an objectList in the normal way, rather than filling in an input slot.

It depends on how you call the factory, if you call factory.update(), that does not directly return an object list. If you use factory.calculate() , that one does return an object list and it will be generated in process, not sent to moi_commandprocessor for async operation.

In v5 you can request for .calculate() to use remote processing by passing a string option 'async' like: .calculate( 'async' ); . if you do that it will internally block using .waitForAsyncUpdate().

When a factory is using remote processing it gathers up parameters and sends it to a separate moi_commandprocessor process and does the actual work over there. That has the expense of some additional transmission overhead but long running operations can be canceled and there is also crash protection where if the processing crashes it will only take down the worker process and not the main Moi process.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  pressure (PEER)
11087.3 In reply to 11087.2 
Thank you Michael for your thorough and speedy answers to my questions! I wouldn't have guessed that I could run any factory asynchronously or that .calculate() forces execution on the main process even for "async factories" except when the new 'async' option is passed.

I'll add all this to the API doc.

- Peer
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
11087.4 In reply to 11087.3 
Hi Peer,

re: this part
> I wouldn't have guessed that I could run any factory asynchronously

Sorry I didn't mean to imply this part, factories will only do an async .update() if they are internally marked with a "do async updates" flag.

What I meant was that the .waitForAsyncUpdate() wasn't implemented just on those 3 particular factories, it's part of the base geometry factory interface.

If you call .waitForAsyncUpdate() when there is not an async update currently in progress it should just be a NOP.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  pressure (PEER)
11087.5 In reply to 11087.4 
Hi Michael,

I was thinking that factory.waitForAsyncUpdate() causes the factory to be processed remotely, but now I'm thinking that it does exactly what the name implies: waits for some event that occurs when an already-running remote process finishes.

It sounds like there are "async factories" that are processed remotely by default when doing factory.update(), like ArrayGem and Twist, and that it's necessary to do factory.waitForAsyncUpdate() after doing factory.update() and before using the results from the update of an async factory.

But, if an async factory is run with factory.calculate() then it will run on the main process rather than remotely.

However, any factory, including async factories, can be processed remotely by doing factory.calculate( 'async' ) and in that case factory.waitForAsyncUpdate() shouldn't be used as the next line in JavaScript, because factory.calculate( 'async' ) is already waiting internally for the remote process to finish.

- Peer
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
11087.6 In reply to 11087.5 
Hi Peer,

re:
> It sounds like there are "async factories" that are processed remotely by default when doing
> factory.update(), like ArrayGem and Twist, and that it's necessary to do factory.waitForAsyncUpdate()
> after doing factory.update() and before using the results from the update of an async factory.

Correct.


> But, if an async factory is run with factory.calculate() then it will run on the main process rather than remotely.

Yes, this is because factory.calculate() returns an object list to the caller.


> However, any factory, including async factories, can be processed remotely by doing factory.calculate( 'async' )
> and in that case factory.waitForAsyncUpdate() shouldn't be used as the next line in JavaScript, because
> factory.calculate( 'async' ) is already waiting internally for the remote process to finish.

Yes, for a while I had this turned on automatically for async factories but it caused some compatibility problems with some of Max's more complex scripts that had timers that can get reentrantly called during the internal waitForAsyncUpdate(). So it's opt-in now.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
 From:  pressure (PEER)
11087.7 In reply to 11087.6 
Thanks for straightening me out Michael and for explaining some of the reasoning behind this setup.

- Peer
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged
 

Reply to All Reply to All