-
Notifications
You must be signed in to change notification settings - Fork 2
/
emitter.js
92 lines (74 loc) · 2.63 KB
/
emitter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Core routines for event emitters
//
var lib = require('./lib')
, util = require('util')
, events = require('events')
, request = require('request')
;
function Emitter (log_label) {
var self = this;
events.EventEmitter.call(self);
self.log = lib.getLogger(log_label ? ('probe_couchdb.'+log_label) : 'probe_couchdb');
// Callbacks can register for "known" states either before or after the information
// actually becomes known. If before, they will queue up until it is known, then run
// in order. Susequent "known" calls will call back immediately.
self.known_state = {};
} // Emitter
util.inherits(Emitter, events.EventEmitter);
Emitter.prototype.request = function request_wrapper(opts, callback) {
var self = this;
function json_body(er, resp, body) {
if(!er) {
try { body = JSON.parse(body) }
catch(e) { er = e }
}
// TODO: Maybe set self.client = resp.client?
return callback && callback.apply(this, [er, resp, body]);
}
opts.proxy = opts.proxy || self.proxy || process.env.http_proxy;
opts.client = opts.client || self.client;
opts.followRedirect = false;
opts.headers = opts.headers || {};
opts.headers.accept = opts.headers.accept || 'application/json';
//opts.headers.Connection = opts.headers.Connection || 'keep-alive';
if(opts.method && opts.method !== "GET" && opts.method !== "HEAD")
opts.headers['content-type'] = 'application/json';
return request.apply(self, [opts, json_body]);
}
Emitter.prototype.known = function on_known(name, cb, newval) {
var self = this;
if(!self.known_state[name])
self.known_state[name] = { known: false
, value: undefined
, callbacks: []
};
var state = self.known_state[name];
if(cb) {
// Fetch the value (either call back now, or register when it is known.
if(! state.known)
state.callbacks.push(cb)
else
return cb && cb.apply(undefined, [state.value]);
} else {
// Store the value, calling back any pending callbacks.
state.known = true;
state.value = newval;
state.callbacks.forEach(function(cb) {
cb && cb.apply(undefined, [newval]);
})
state.callbacks = [];
}
}
// If event A triggers event B, B should wait to emit until A is finished.
Emitter.prototype.x_emit = function push_emit() {
var self = this
, args = arguments;
process.nextTick(function() {
// Actually emit the event.
self.emit.apply(self, args)
// Also register that the value is known.
self.known(args[0], null, args[1]);
})
}
module.exports = { "Emitter" : Emitter
};