Permalink
Browse files

working with mongodb

  • Loading branch information...
1 parent 5ec012d commit a2238beaef96899156bab47a100d5549760628ca @indutny committed Dec 2, 2010
Showing with 171 additions and 136 deletions.
  1. +17 −0 config.json
  2. +71 −60 lib/tracker/db.mongo.js
  3. +5 −6 lib/tracker/querydecoder.js
  4. +9 −8 lib/tracker/router.js
  5. +43 −51 lib/tracker/storage.mongo.js
  6. +2 −1 package.json
  7. +12 −0 run
  8. +12 −10 run.js
View
17 config.json
@@ -0,0 +1,17 @@
+{
+ "server": {
+ "port": 8081
+ },
+ "db": {
+ "port": 5984,
+ "host": "indutny.couchone.com",
+ "database": "tracker",
+ "auth": {
+ "user": "admin",
+ "pass": "admin"
+ },
+ "setup": true,
+ "engine": "mongo",
+ "mongo_url": "mongodb://localhost/tracker"
+ }
+}
View
131 lib/tracker/db.mongo.js
@@ -1,67 +1,78 @@
/**
* Init db
*/
-var cradle = require('../../support/mongoose');
+var mongoose = require('../../support/mongoose'),
+ document = mongoose.define;
-module.exports = function(options, callback) {
- cradle.setup({
- host: options.host,
- port: options.port,
- options: options.options
- });
- var connection = new (cradle.Connection)({auth: options.auth}),
- db = connection.database(options.database);
-
- options.setup ? setup(db, callback) : callback(null, db);
-};
+module.exports = function(options, callback) {
+ var db = mongoose.connect(options.mongo_url);
+
+ document('Peer')
+ .oid('_id')
+ .string('peer_id')
+ .string('info_hash')
+ .string('short_addr')
+ .string('ip')
+ .number('port')
+ .number('left')
+ .number('updated_at')
+ .addIndex({peer_id: 1, info_hash: 1}, {unique: true, dropDubs: true})
+ .addIndex({info_hash: 1})
+ .addIndex({updated_at: -1})
+ .static('cleanup', function cleanup(since) {
+ this.remove({updated_at: {$lt: since}}, function() {});
+ });
+ db.Peer = mongoose.Peer;
+
+ document('Cache')
+ .oid('_id')
+ .string('info_hash')
+ .string('peers')
+ .number('updated_at')
+ .addIndex({info_hash: 1}, {unique: true, dropDubs: true})
+ .addIndex({updated_at_at: -1})
+ .static('cleanup', function cleanup(since) {
+ this.remove({updated_at: {$lt: since}}, function() {});
+ })
+ .static('access', function access(info_hash, callback) {
+ this.find({info_hash: info_hash}).one(function(err, cache) {
+ if (err) return callback(err);
+
+ if (!cache) {
+ db.Peer
+ .find({info_hash: info_hash})
+ .sort([['updated_at', -1]])
+ .limit(50)
+ .all(function(err, docs) {
+ if (err) return callback(err);
+
+ var peers = docs.map(peer_id).join('');
-function setup(db, callback) {
- var views = {
- by_update_time: {
- map: function(doc) {
- if (doc.type == 'peer') {
- emit(doc.updated_at, {_id: doc._id, _rev: doc._rev});
- }
- }
- },
- by_hash: {
- map: function(doc) {
- if (doc.type == 'peer') {
- var ip = doc.ip.split('.'),
- port = String.fromCharCode(doc.port >> 8, doc.port % 256);
-
- emit([doc.info_hash, doc.updated_at],
- String.fromCharCode.apply('', ip) + port);
+ callback(null, peers);
+
+ new (db.Cache)({
+ info_hash: info_hash,
+ peers: escape(peers),
+ updated_at: +new Date
+ }).save();
+ });
+ } else {
+ callback(null, unescape(cache.peers));
}
- },
- reduce: function(keys, values, rereduce) {
- return values.join('');
- }
- },
- seeders_by_hash: {
- map: function(doc) {
- if (doc.type == 'peer' && doc.left) {
- emit(doc.info_hash, 1);
- }
- },
- reduce: function(keys, values) {
- return sum(values);
- }
- },
- leechers_by_hash: {
- map: function(doc) {
- if (doc.type == 'peer' && !doc.left) {
- emit(doc.info_hash, 1);
- }
- },
- reduce: function(keys, values) {
- return sum(values);
- }
- }
- };
+ });
+ });
+ db.Cache = mongoose.Cache;
- db.save('_design/tracker', views, function(err) {
- if (err) return callback(err);
- callback(null, db);
- });
-}
+ callback(null, db);
+};
+
+
+/**
+* Generate peer_id
+*/
+function peer_id(peer) {
+ var ip = peer.ip.split('.'),
+ port = String.fromCharCode(peer.port >> 8, peer.port % 256);
+
+ return String.fromCharCode.apply('', ip) + port;
+};
View
11 lib/tracker/querydecoder.js
@@ -4,13 +4,12 @@
var qs = require('querystring');
module.exports = function(req, res, next) {
-
- if (match = req.url.match(/\?(.+)$/)) {
+ req.query = {};
+ if (match = req.url.match(/\?(.+)$/)) {
+ match[1].replace(/([^=]*)=([^&]*)&?/g, function(a, key, value) {
+ req.query[key] = unescape(value);
+ });
- req.query = qs.parse(match[1]);
-
- } else {
- req.query = {};
}
next();
}
View
17 lib/tracker/router.js
@@ -4,18 +4,19 @@
var connect = require('connect'),
bencode = require('./bencode'),
error = require('./error'),
- querydecoder = require('./querydecoder'),
- Storage = require('./storage'),
+ querydecoder = require('./querydecoder'),
helpers = require('./helpers');
module.exports = function(db, options, callback) {
var server = connect.createServer(
- bencode,
- error,
- querydecoder,
- connect.router(router),
- connect.staticProvider(__dirname + '/../../public')
- );
+ bencode,
+ error,
+ querydecoder,
+ connect.router(router),
+ connect.staticProvider(__dirname + '/../../public')
+ ),
+ Storage = require('./storage' + options.db.engine_postfix);
+
server.listen(options.server.port, options.server.host);
var storage = new Storage(db, options);
View
94 lib/tracker/storage.mongo.js
@@ -26,83 +26,75 @@ Storage.prototype.route = function(event, peer, callback) {
* Remove peer from database
*/
Storage.prototype.stop = function(peer, callback) {
- var db = this._db,
- _id = peer_id(peer);
+ console.log('stop');
+ var db = this._db;
- db.get(_id, function(err, doc) {
- if (err) return callback(err);
- db.remove(_id, doc._rev, function(err, res) {
- if (err || !res.ok) return callback(err || res);
-
- callback();
- });
- });
+ db.Peer.remove({peer_id: peer.peer_id, info_hash: info_hash}, callback);
};
/**
* Put peer into database
*/
Storage.prototype.put = function(event, peer, callback) {
+ console.log('put');
var db = this._db,
- _id = peer_id(peer),
that = this;
-
+
peer.updated_at = +new Date;
- peer.type = 'peer';
- db.save(_id, peer, finish);
-
- function finish(err, res) {
- if (err || !res.ok) return callback(err || res);
-
- that.list(peer, callback);
- };
+
+ db.Peer
+ .find({peer_id: peer.peer_id, info_hash: peer.info_hash})
+ .one(function(err, instance) {
+ if (err) return callback(err);
+
+ if (!instance) {
+ // Create
+ console.log('creating');
+ instance = new (db.Peer)(peer);
+ console.log('created');
+ } else {
+ // Update
+ instance.updated_at = peer.updated_at;
+ }
+ console.log('saving');
+ instance.save(function(err) {
+ if (err) return callback(err);
+
+ that.list(peer, callback);
+
+ });
+ });
};
/**
* Get peer list by info_hash (without current peer)
*/
Storage.prototype.list = function(peer, callback) {
+ console.log('list');
var options = this._options,
db = this._db;
- db.view('tracker/by_hash', {key: peer.info_hash, limit: 50,
- descending: true, group_level: 1},
- function(err, rows) {
- if (err) return callback(err);
-
- var peers = rows[0] && rows[0].value;
-
- var result = {
- interval: options.announce_interval,
- 'min interval': options.announce_min_interval,
- peers: peers
- };
- callback(null, result);
- });
+ db.Cache.access(peer.info_hash, function(err, peers) {
+ if (err) return callback(err);
+
+ var result = {
+ interval: options.announce_interval,
+ 'min interval': options.announce_min_interval,
+ peers: peers
+ };
+ callback(null, result);
+ });
};
/**
* Remove old revisions of documents
* Remove stale documents
*/
Storage.prototype.cleanup = function() {
- var db = this._db;
+ var db = this._db,
+ since = +new Date - this._options.announce_interval * 2000;
- db.compact();
- db.view('tracker/by_update_time',
- {endKey: +new Date - this._options.announce_interval * 2000},
- function(err, rows) {
- if (err) return;
-
- rows.map(function(peer) {
- db.remove(peer._id, peer._rev);
- });
- });
+ db.Peer.cleanup(since);
+ db.Cache.cleanup(since);
};
-/**
-* Generate peer_id
-*/
-function peer_id(peer) {
- return peer.info_hash + ':' + peer.ip + ':' + peer.port;
-};
View
3 package.json
@@ -5,7 +5,8 @@
"cradle": ">=0.2.3",
"vows": ">=0.5.2",
"connect": ">=0.3.0",
- "mongoose": ">=0.0.3"
+ "mongoose": ">=0.0.3",
+ "optimist": ">=0.1.1"
},
"version" : "0.1.0",
"engines" : { "node": ">=0.3.1" }
View
12 run
@@ -0,0 +1,12 @@
+#!/usr/bin/env node
+
+/**
+* Pseudo-cli
+*/
+var tracker = require('./lib/tracker'),
+ argv = require('optimist')
+ .usage('Usage: $0 --config config.json')
+ .demand('config')
+ .argv;
+
+tracker(JSON.parse(fs.readFileSync(argv.config)));
View
22 run.js
@@ -4,17 +4,19 @@
var tracker = require('./lib/tracker');
tracker({
- server: {
- port: 8081
+ "server": {
+ "port": 8081
},
- db: {
- port: 5984,
- host: 'indutny.couchone.com',
- database: 'tracker',
- auth: {
- user: 'admin',
- pass: 'admin'
+ "db": {
+ "port": 5984,
+ "host": "indutny.couchone.com",
+ "database": "tracker",
+ "auth": {
+ "user": "admin",
+ "pass": "admin"
},
- setup: true
+ "setup": true,
+ "engine": "mongo",
+ "mongo_url": "mongodb://localhost/tracker"
}
});

0 comments on commit a2238be

Please sign in to comment.