Skip to content

Instantly share code, notes, and snippets.

@dipunm
Created March 26, 2018 20:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dipunm/c62fc4fa9dc4a9b6c5ab9e6216ef9810 to your computer and use it in GitHub Desktop.
Save dipunm/c62fc4fa9dc4a9b6c5ab9e6216ef9810 to your computer and use it in GitHub Desktop.
const Tracker = {
Lift: function(value) {
return new Tracker.Monad({}, value);
},
Record: function(state) {
return new Tracker.Monad(state);
},
Errored: function(err) {
return new Tracker.Monad({error: err});
},
completeAndRecordTimer: function(timer) {
timer.stop();
return Tracker.Record({
timeElapsed: timer.elapsed,
completed: true
});
},
Monad: class {
constructor({
timeElapsed = 0,
count = 0,
dateOfLastUpdated = null,
completed = false,
error
}, value) {
this.state = {
timeElapsed,
count,
dateOfLastUpdated,
completed,
error
};
this.value = value;
}
bind(fn) {
if(this.state.completed === true) {
return this;
}
const newM = fn(this.value)
if(this.state.completed === false) {
return new Tracker.Monad({
timeElapsed: this.state.timeElapsed + newM.timeElapsed,
count: this.state.count,
dateOfLastUpdated: this.state.dateOfLastUpdated,
completed: false,
error: this.state.error
}, newM.value);
}
return new Tracker.Monad({
timeElapsed: this.state.timeElapsed + newM.timeElapsed,
count: this.state.count + newM.count,
dateOfLastUpdated: newM.dateOfLastUpdated,
completed: newM.completed,
error: newM.error
}, newM.value);
}
}
}
class MonadicCursor extends Cursor {
constructor(cursor) {
super(cursor);
}
readNext(n) {
super.readNext(n)
.then(data => Tracker.Lift(data))
.catch(err => Tracker.Errored(err));
}
}
class MonadicSolrClient {
sendData(data) {
super.sendData()
.then(success =>
success ? Tracker.Record({
count: data.length,
dateOfLastUpdated: data[data.length - 1].updateDate
}).bind(Tracker.Lift(true)) :
Tracker.Record({
completed: false
}).bind(Tracker.Lift(false))
);
}
}
function runMonadic(func, ...args){
const it = func(...args);
function cont(lastVal) {
const {done, value: m} = it.next(lastVal);
return done ? m.bind(cont) : m;
}
return cont();
}
async function* syncDataToSolr(lastUpdated) {
var query = new Query(lastUpdated);
const cursor = mongo.dispatch(query);
const timer = startTiming();
while(await cursor.hasNext()) {
const data = yield await cursor.readNext(100);
yield await solrClient.sendData(data);
}
yield Tracker.completeAndRecordTimer(timer);
}
var result = runMonadic(syncDataToSolr, Date.yesterday());
@dipunm
Copy link
Author

dipunm commented Mar 27, 2018

NODE V8
node --harmony-async-iteration monads.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment