ASync method handling and queuing. Got an idea for a haxelib tool - do we need it?

53 views
Skip to first unread message

Creative Magic

unread,
May 22, 2017, 3:34:06 AM5/22/17
to Haxe
Hi dear community,

I've made a small utility for a problem I had to solve. This utility had to sequence a whole bunch of methods, some of those methods were async and some of the were synchronous.

The utility is working fine and I found myself using it across different applications as well! Here's some code snippets to illustrate use of the utility:

class Controller
{
 
 
public function authenticate():IRequestAction // IRequestAction basically has 4 methods - to add success/error call backs and to call those.
 
{
 
var authenticateRequest:IRequestAction= new Authenticate();
  return authenticateRequest;
 }
 
 
public function loadTweetData( tweetId:String ):IRequestAction
 
{
 
var loadTweetDataRequest:IRequestAction= new LoadTweetData(tweetId);
  return loadTweetDataRequest;
 }
 
public function downloadCSVFile():IRequestAction
{
var downloadCSVFileRequest:IRequestAction = new ExportRetweetingUserDataAsCSV();
return downloadCSVFileRequest;
}


 
// More of similar methods below
}

So any "action" method that you want to perform: loading data, sorting, searching etc., can be written in it's own class. And so long as it's implementing a simple IRequestAction interface, you can call them like so:

Controller.controllerInstance.loadRetweetData(tweetId).onSuccess( onRetweetDataLoadSuccess).onError(onRetweetDataLoadError );

I liked chaining the methods like this from long ago when I were using MaxTween tweener. Joshua's Actuate tweener feels very similar to that.
And yes, if you put your action implementation into the constructor (so it would execute before you can add success/error handlers) - it would still call the handler you need once it's added.

The next thing I've done is making a queue manager for actions, so you can write something like this:


function setupStartupActionQueue():Void
 
{
 
var actionQueue = new ActionQueue();
  actionQueue.addAction( Controller.controllerInstance.loadTweetData("") ); // you can actually add handlers to the actions here too!
  actionQueue.addAction( Controller.controllerInstance.loadRetweetData("") );
  actionQueue.addAction( Controller.controllerInstance.loadListOfRetweetingUsers([]) );
  actionQueue.addAction( Controller.controllerInstance.updateSessionFile() );
  actionQueue.addEventListener( ActionQueueEvent.QUEUE_COMPLETE, onQueueComplete);
  actionQueue.startQueue();
 }


The benefit of this utility is to write cleaner code. Every action does one thing, it has it's own class for that. With this utility it's transparent and easy to manage.

But I'm not 100% sure that it's:

  1. Not a duplicate of some other well-known library
  2. Really the preferred way of writing code and follows all the Best Practices

I'd like to get some feedback from you:

  • Would you be interested to see this utility published (it's used for OpenFL, but isn't really depending on any other library, the event system of OpenFL that I've used can be easily removed)
  • What features are important for you to have to make it usable?
  • If you have ideas about API and how to work with this tool more efficiently - let me know.


Juraj Kirchheim

unread,
May 22, 2017, 5:30:36 AM5/22/17
to haxe...@googlegroups.com
You can use promhx, thx.core or tink_core to use promises, which are a "standard" way of modelling asynchronous operations. Promises all have some type of queuing built in. Here's one way how you might do such a thing with tink_core: https://try.haxe.org/#5eCf6

The controller is a complete dummy of course. What might confuse you about it is that both errors and synchronously returned data can act as promise, which is achieved through implicit casts to save you some writing.

Generally you will find there are various differences between how these libraries approach the subject and every author will have their own reasons. Whether or not they fit you well, depends on you. What sets them apart can may be summarized like so (I hope I'm doing Justin and Franco justice here):

- promhx is relatively close to the ECMAScript 6 promises standard, which is an advantage in that a growing number of people are familiar with it.
- thx.core has its own ideas about promises and goes the extra mile to deal with varying arity and tuples. And of course it integrates well with the rest of the thx libraries.
- tink_core has a relatively similar approach to promises as thx.core, but it is a bit leaner and favors laziness, which you may find beneficial or confusing. It also leverages implicit casts quite strongly to simplify its interface, and of course it generally integrates more smoothly with the other tink libraries.

Whether or not you want to use any of these libraries, I think you will find it worth while to have a look at them. The most important aspect here I think is that you use generics to have a strictly typed result type, as in IRequestAction<Data> so that the onSuccess callback is type safe.

Best,
Juraj

--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
---
You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/d/optout.

funplo...@gmail.com

unread,
May 22, 2017, 6:53:11 AM5/22/17
to Haxe
Oh, right, promises can actually cover this. I forgot about them somehow.
I guess that's the effect of late-night programming, you end up writing a whole thing just to remember that it's already supported.

Thanks! :)
Reply all
Reply to author
Forward
0 new messages