UNPKG

6.34 kBJavaScriptView Raw
1(function() {
2 var Client, Linda, Tuple, TupleSpace, debug, events, fs, http, path, socketio, url,
3 __hasProp = {}.hasOwnProperty,
4 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
5
6 http = require('http');
7
8 path = require('path');
9
10 url = require('url');
11
12 fs = require('fs');
13
14 events = require('eventemitter2');
15
16 socketio = require('socket.io');
17
18 debug = require('debug')('linda');
19
20 TupleSpace = require(path.join(__dirname, 'tuplespace'));
21
22 Tuple = require(path.join(__dirname, 'tuple'));
23
24 Client = require(path.join(__dirname, 'linda-client'));
25
26 module.exports.TupleSpace = TupleSpace;
27
28 module.exports.Tuple = Tuple;
29
30 module.exports.Client = Client;
31
32 Linda = (function(_super) {
33 __extends(Linda, _super);
34
35 function Linda() {
36 this.spaces = {};
37 fs.readFile(path.join(__dirname, 'linda-client.js'), (function(_this) {
38 return function(err, data) {
39 if (err) {
40 throw new Error("client js load error");
41 }
42 return _this.client_js_code = data;
43 };
44 })(this));
45 setInterval((function(_this) {
46 return function() {
47 var name, space, _ref;
48 debug("TupleSpace\tcheck expire");
49 _ref = _this.spaces;
50 for (name in _ref) {
51 space = _ref[name];
52 if (space != null) {
53 space.check_expire();
54 }
55 }
56 return debug("TupleSpace\tcheck expire done");
57 };
58 })(this), 60 * 3 * 1000);
59 }
60
61 Linda.prototype.tuplespace = function(name) {
62 return this.spaces[name] || (this.spaces[name] = new TupleSpace(name));
63 };
64
65 Linda.prototype.listen = function(opts) {
66 if (opts == null) {
67 opts = {
68 io: null,
69 server: null
70 };
71 }
72 if (opts.io == null) {
73 throw new Error('"io" must be instance of Socket.IO');
74 }
75 if (!(opts.server instanceof http.Server)) {
76 throw new Error('"server" must be instance of http.Server');
77 }
78 this.io = opts.io;
79 this.server = opts.server;
80 this.oldListeners = this.server.listeners('request').splice(0);
81 this.server.removeAllListeners('request');
82 this.server.on('request', (function(_this) {
83 return function(req, res) {
84 var listener, _i, _len, _ref, _results, _url;
85 _url = url.parse(decodeURI(req.url), true);
86 if (_url.pathname === "/linda/linda.js") {
87 debug("GET\t" + _url.pathname);
88 res.setHeader('Content-Type', 'application/javascript');
89 res.writeHead(200);
90 res.end(_this.client_js_code);
91 return;
92 }
93 _ref = _this.oldListeners;
94 _results = [];
95 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
96 listener = _ref[_i];
97 _results.push(listener.call(_this.server, req, res));
98 }
99 return _results;
100 };
101 })(this));
102 this.io.sockets.on('connection', (function(_this) {
103 return function(socket) {
104 var cids, info, watch_cids;
105 cids = {};
106 info = {
107 from: socket.handshake.headers['x-forwarded-for'] || socket.handshake.address.address
108 };
109 socket.on('__linda_write', function(data) {
110 var _ref;
111 if ((_ref = data.options) != null) {
112 _ref.from = info.from;
113 }
114 _this.tuplespace(data.tuplespace).write(data.tuple, data.options);
115 debug("write\t" + (JSON.stringify(data)) + " from " + info.from);
116 return _this.emit('write', data);
117 });
118 socket.on('__linda_take', function(data) {
119 var cid;
120 cid = _this.tuplespace(data.tuplespace).take(data.tuple, function(err, tuple) {
121 cid = null;
122 return socket.emit("__linda_take_" + data.id, err, tuple);
123 });
124 cids[data.id] = cid;
125 debug("take\t" + (JSON.stringify(data)) + " from " + info.from);
126 _this.emit('take', data);
127 return socket.once('disconnect', function() {
128 if (cid) {
129 return _this.tuplespace(data.tuplespace).cancel(cid);
130 }
131 });
132 });
133 socket.on('__linda_read', function(data) {
134 var cid;
135 cid = _this.tuplespace(data.tuplespace).read(data.tuple, function(err, tuple) {
136 cid = null;
137 return socket.emit("__linda_read_" + data.id, err, tuple);
138 });
139 cids[data.id] = cid;
140 debug("read\t" + (JSON.stringify(data)) + " from " + info.from);
141 _this.emit('read', data);
142 return socket.once('disconnect', function() {
143 if (cid) {
144 return _this.tuplespace(data.tuplespace).cancel(cid);
145 }
146 });
147 });
148 watch_cids = {};
149 socket.on('__linda_watch', function(data) {
150 var cid;
151 debug("watch\t" + (JSON.stringify(data)) + " from " + info.from);
152 _this.emit('watch', data);
153 if (watch_cids[data.id]) {
154 return;
155 }
156 watch_cids[data.id] = true;
157 cid = _this.tuplespace(data.tuplespace).watch(data.tuple, function(err, tuple) {
158 return socket.emit("__linda_watch_" + data.id, err, tuple);
159 });
160 cids[data.id] = cid;
161 return socket.once('disconnect', function() {
162 if (cid) {
163 return _this.tuplespace(data.tuplespace).cancel(cid);
164 }
165 });
166 });
167 return socket.on('__linda_cancel', function(data) {
168 debug("cancel\t" + (JSON.stringify(data)) + " from " + info.from);
169 _this.emit('cancel', data);
170 _this.tuplespace(data.tuplespace).cancel(cids[data.id]);
171 return watch_cids[data.id] = false;
172 });
173 };
174 })(this));
175 return this;
176 };
177
178 return Linda;
179
180 })(events.EventEmitter2);
181
182 module.exports.Linda = new Linda;
183
184}).call(this);