Giter Site home page Giter Site logo

metarhia / metasync Goto Github PK

View Code? Open in Web Editor NEW
205.0 24.0 34.0 1.22 MB

Asynchronous Programming Library for JavaScript & Node.js

Home Page: https://metarhia.com

License: MIT License

JavaScript 99.61% Shell 0.39%
node nodejs js javascript async asynchronous callback parallel series composition

metasync's People

Contributors

anxolerd avatar aqrln avatar arthur-here avatar belochub avatar dzyubspirit avatar hamidzr avatar ivan-tymoshenko avatar juliagerasymenko avatar nazarponochevnyi avatar nechaido avatar o-rumiantsev avatar primeare avatar semenchenkovitaliy avatar timursevimli avatar tshemsedinov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

metasync's Issues

Proposal: rebranding and functionality change

@tshemsedinov, what do you think about turning MetaSync (under some new name) into a full-blown generic library of utility functions for JavaScript with asynchronous utilities being only a part of it? We definitely need some sort of common library since I've encountered situations when two analogous functions have to be fixed twice in Impress and JSTP.

Refs: metarhia/Metarhia#2

Change DataCollector interface

// expect 4 data keys
var dc1 = new metasync.DataCollector(4);

// expect 4 data keys within 5 second timeout
var dc2 = new metasync.DataCollector(4, 5000);

dc1.on('error', function(err, key) { ... });
dc2.on('timeout', function(err, data) { ... });
dc2.on('done', function(errs, data) {
  // errs - hash of errors
  // data - hash of successfully received data
});

FYI: @aqrln, @belochub, @DzyubSpirit

Implement .map(items, callback, done)

Use case:

metasync.map(['Beijing', 'Roma', 'Kiev'], (item, callback) => {
  getCityPopulation(item, (count) => {
    callback(count);
  });
}, (err, arr) => {
  let total = arr.reduce((prev, cur) => (prev + cur), 0);
  console.log('Total population: ' + total);
});

Collect same key twice

In 88#discussion_r115333601 @aqrln noticed that collector now increments counter even on same keys. On the one hand it's lightweight but on the other it may lead to errors in applied code. So I'd prefer to have both implementation:

  • metasync.collect(3)
  • metasync.collect(3).distinct()

Rename metasync.composition to flow

Actually metasync.composition not returning composed function so this name is not the best choice. I'd prefer to rename it to something related with flow control or function commutation. For ecample:

metasync.flow([...])(data, (err, data) => {});

FYI @aqrln @nechaido @belochub

Implement Throttle

var t1 = metasync.throttle(5000, func);
t1(); t1(); t1(); // single call
setTimeout(t1, 7000); // another call

Callback wrapper

Here is an idea of small but useful callback wrapper.
After applying metasync.cb:

  • no need to check like this: if (callback) return callback(err, data);
  • wrapper prevents to call it more then once
  • it may optionally add debugging wraper to trace async code (not for production)
    Usage:
const doSomethingAsync = (par1, parN, callback) => {
  const cb = metasync.cb(callback); // apply wrapper
  // ... some code here ...
  // No need to check: if (cb) return ....
  cb(err, data); // first call will be passed to callback
  return cb(err, data); // second will write warning to console or log
};

Implement .reduce(items, callback, done, initial)

Use case:

metasync.reduce(['Beijing', 'Roma', 'Kiev'], (prev, cur, callback) => {
  getCityPopulation(cur, (count) => {
    callback(prev + count);
  });
}, (err, count) => {
  console.log('Total population: ' + count);
}, 0);

Implement KeyCollector

var keyCollector = new metasync.KeyCollector(
  ['user', 'config', 'readme', 'timer'],
  function(data) {
    console.dir(Object.keys(data));
    console.log('Collector test done');
    end('KeyCollector');
  }
);

keyCollector.collect('user', { name: 'Marcus Aurelius' });

fs.readFile('HISTORY.md', function(err, data) {
  keyCollector.collect('history', data);
});

fs.readFile('README.md', function(err, data) {
  keyCollector.collect('readme', data);
});

setTimeout(function() {
  keyCollector.collect('timer', { date: new Date() });
}, ASYNC_TIMEOUT);

Implement metasync.ConcurrentQueue

var queue = new metasync.ConcurrentQueue(concurrency, timeout);
queue.add({item});
queue.on('empty', fn);
queue.on('process', fn(item, callback));
queue.pause();
queue.resume();
queue.stop();

Chaining implementation comparison

Here we have 5 branches:

I'm afraid that promises will affect performance and they may be not so effectivу.
I think they also use something like nextTick to fire chain.
That's because I like manual .fire()
What do you think @aqrln ?

Add options

options: {
  expected: 4, // expected data pices for DataCollector
  timeout: 5000, // global timeout
  each: 1000, // timeout for each function
  error: { // TODO: invent better options structure
    finish: true // finish on error if true
  },
  on: {
    done: function(err, data) { // on finish
    },
    timeout: function(err, data) { // on timeout
    }
  }
}

Alternative chaining syntax for collectors

const dc1 = metasync
  .collect(3)
  .timeout(5000)
  .done((err, data) => {});

dc1(item);

const dc2 = metasync
  .collect(['key1', 'key2', 'key3'])
  .timeout(5000)
  .done((err, data) => {});

dc2(key, value);

WDYT, @aqrln about .timeout(number) and firing .catch on timeout ?

Alternative chaining syntax for Queue

We have ConcurrentQueue in lib/queue.js but new chaining metasync.queue may implement more features from Queueing theory:

  • Prioritized queueing
  • Ordering: FIFO/LIFO
  • Process throttling
  • Balancing
  • Timeouts
  • Statistics and optimization
const cq = metasync.queue(3) // concurrency
  .wait(2000) // task may wait in queue not more then 2 sec
  .timeout(5000) // task processing timeout 5 sec
  .throttle(100, 1000) // throttle processing to 100 rps
  .process((item, cb) => cb(err, result)) // task processing function
  .success((item) => {}) // on success
  .failure((item) => {}) // on fail
  .drain(() => {}); // on drain

@aqrln @belochub @nechaido @DzyubSpirit maybe you need more in JSTP or can add something for GlobalStorage or Impress use cases?

Alternative chaining syntax for..each

As we mentioned in #17 it would be great to have better syntax, chaining:

metasync.for(items).each(fn).fetch(fn);

metasync.for(items).reduce(fn).fetch(fn);

metasync.for(items).filter(fn).map(fn).then(fn).reduce(fn).fetch(fn);

Storing error in collectors

Chaining optimization

Maybe it is better to have consistent function signature in chaining.
Now in following example fn1 and fn2 have different signature then fn3 and fn4:

api.metasync.for(array).filter(fn1).map(fn2).then(fn3).catch(fn4);
  • Signature for fn1 and fn2 is: (element, callback) => callback(error, result)
  • Signature for fn3 is: (data) => {}
  • Signature for fn4 is: (error) => {}
    But we can combine .then() and .catch() into .done()
api.metasync.for(array).filter(fn1).map(fn2).done(fn3);

Signature for fn1 and fn2 will be: (element, callback) => callback(err, result)
But here is 2 alternative syntax for f3:

  • (data, callback) => callback(error, data) where result may be instance of Error or data
  • (error, data, callback) => callback(error, data)
    We need callback in .done() because chaining may contain multiple steps after .done()
    For example:
api.metasync.for(array).filter(fn1).map(fn2).done(fn3).reduce(fn4).done(fn5);

@aqrln what do you think?

Impement asyncronous series

metasync.series(
  ['a', 'b', 'c'],
  function iterator(item) { callback(); },
  function done(data) { ... }
);

metasync.map with empty array

metasync.map doesn't call done function when is called with empty array. I think it's good to call done immediately instead of not calling at all.

Refactor to ES6

Refactor and remove old Node.js support.
MetaSync will support just Node.js 6.x and 7.x

Broken test

Tests for metasync.filter and metasync.find are broken due to missing err argument in callback.

Do not use Array.forEach

In .map() and .filter() we use .forEach but we can't break on error, so better to iterate with loops.

Handle errors

  • callback(err, data)
  • stop everything if function returns error (optional)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.