ember-concurrency icon indicating copy to clipboard operation
ember-concurrency copied to clipboard

feature: registering disposables

Open machty opened this issue 7 years ago • 2 comments

I'd like to have a nice first class api for registering disposables on the current task that are cleaned up when the task completes to handle use cases like: https://github.com/brianc/node-pg-pool#plays-nice-with-asyncawait

Specifically I'd like to avoid the pattern of using finally for all cleanup, which is error prone and defensive-programing-y.

Here's a twiddle of an experimental API using defer as inspired by Go to improve upon the typeahead search:

https://ember-twiddle.com/ee1c10f7855c564b439f21c66e8ec33c?numColumns=2&openFiles=controllers.application.js%2Ctemplates.application.hbs

So we could rewrite this example as:

myTask: task(function * () {
  var client = yield pool.connect()
  yield defer(() => client.release());
  var result = yield client.query('select $1::text as name', ['brianc'])
  console.log('hello from', result.rows[0])
});

We could also do C# style using statement a la:

Pool.prototype[DISPOSABLE] = function() {
  this.release();
};

myTask: task(function * () {
  yield using(pool.connect(), function *() {
    var result = yield client.query('select $1::text as name', ['brianc'])
    console.log('hello from', result.rows[0])
  });
});

machty avatar Apr 04 '17 21:04 machty

nice. I know it's not analagous, but could we implement a similar pattern for cancellation/errors too? this makes me want to do pattern matching

myTask: task(function * () {
  var t1 = yield catchAndReturn(this.get('cancelableTask').perform(), () => 'Errored on first task'));
  var t2 = yield catchAndReturn(this.get('cancelableTask').perform(t1.value), () => 'Errored on second task')
  return t2.value;
});

instead of

myTask: task(function * () {
  try {
   var t1 = yield this.get('cancelableTask').perform();
   try { 
      var t2 = yield this.get('cancelableTask').perform(t1.value);
      return t2.value;
    } catch (e) { 
       return 'Errored on Second';
    }
  } catch (e) {
    return 'Errored on first';
  }
});

alexander-alvarez avatar Apr 04 '17 22:04 alexander-alvarez

There a couple of concepts that woth noting: https://github.com/ReactiveX/RxSwift/blob/master/Documentation/GettingStarted.md

Including disposeBag which could be applied like .drop etc

Blackening999 avatar Jun 09 '17 03:06 Blackening999