schangxiang@126.com
2025-09-19 0821aa23eabe557c0d9ef5dbe6989c68be35d1fe
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
93
94
95
96
97
98
99
const Class = require('cify').Class;
const utils = require('ntils');
const net = require('net');
const split = require('split');
const consts = require('./consts');
const oneport = require('oneport');
 
/**
 * 锁管理 Server
 **/
const Server = new Class({
 
  /**
   * 构造
   **/
  constructor: function (options) {
    options = options || {};
    this.options = options;
    this._lockers = {};
  },
 
  /**
   * 审申指定名称的锁
   * @param {String} name 锁名称
   * @param {Function} action 申请成功后的动作
   **/
  acquire: function (name, action) {
    action = utils.isFunction(action) ? action : consts.NOOP;
    this._lockers[name] = this._lockers[name] || new Server.Locker();
    var locker = this._lockers[name];
    locker.actionStack.push(action);
    if (locker.locked) return;
    locker.locked = true;
    this._execute(name);
  },
 
  /**
   * 执行申请锁的动作(这里会触发通知 client 执行)
   **/
  _execute: function (name) {
    var locker = this._lockers[name];
    if (!locker) return;
    var action = locker.actionStack.shift();
    if (utils.isFunction(action)) action();
  },
 
  /**
   * 释放指定名称的锁
   * @param {String}  name 锁名称
   * @param {Function} 释放成功后的回调
   **/
  release: function (name, callback) {
    callback = utils.isFunction(callback) ? callback : consts.NOOP;
    var locker = this._lockers[name];
    if (locker && locker.actionStack.length > 0) {
      this._execute(name);
    } else {
      delete this._lockers[name];
    }
    return callback();
  },
 
  /**
   * 启动锁管理 server
   * @param {Function} callback 启动成功时的回调
   **/
  start: function (callback) {
    callback = utils.isFunction(callback) ? callback : consts.NOOP;
    this._server = net.createServer(function (socket) {
      socket.pipe(split()).on('data', function (data) {
        if (!data) return;
        var info = data.toString().split(',');
        this[info[0]]([info[1]], function () {
          socket.write(info[2] + '\n');
        });
      }.bind(this));
    }.bind(this));
    this._server.on('error', callback);
    oneport.acquire(consts.PORT_KEY, function (err, port) {
      if (err) return callback(err);
      this._server.listen(port, consts.HOST, callback);
    }.bind(this));
  }
 
});
 
/**
 * 服务端 Locker 类
 **/
Server.Locker = new Class({
 
  constructor: function () {
    this.actionStack = [];
    this.locked = false;
  }
 
});
 
module.exports = Server;