UNPKG

4.35 kBJavaScriptView Raw
1(function() {
2 var bindExit, findDeep, fs, isRunning, lock, lockfile, path, unbindExit;
3
4 lockfile = require('lockfile');
5
6 fs = require('fs');
7
8 path = require('path');
9
10 isRunning = function(pid) {
11 var e;
12 try {
13 process.kill(pid, 0);
14 } catch (error) {
15 e = error;
16 return false;
17 }
18 return true;
19 };
20
21 exports.lock = lock = function(name, status, configPath, configData, cb) {
22 var lockPath, pidPath, verification;
23 lockPath = path.join(path.dirname(configPath), name + ".lock");
24 pidPath = path.join(path.dirname(configPath), name + ".pid");
25 verification = {
26 lockPath: lockPath,
27 pidPath: pidPath
28 };
29 return lockfile.lock(lockPath, {}, function(err) {
30 var fail;
31 if (err != null) {
32 fail = function() {
33 console.error("File " + lockPath + " already exists: is another instance running?", err);
34 return process.exit(1);
35 };
36 return fs.exists(pidPath, function(exists) {
37 if (exists) {
38 return fs.readFile(pidPath, {
39 encoding: 'utf8'
40 }, function(err, data) {
41 var pidobj;
42 if (err != null) {
43 return cb(err);
44 }
45 pidobj = JSON.parse(data);
46 if (!isRunning(pidobj.pid)) {
47 fs.unlinkSync(pidPath);
48 fs.unlinkSync(lockPath);
49 return lock(name, status, configPath, configData, cb);
50 } else {
51 return fail();
52 }
53 });
54 } else {
55 return fail();
56 }
57 });
58 } else {
59 return fs.writeFile(pidPath, JSON.stringify(status), {
60 encoding: 'utf8'
61 }, function(err) {
62 if (err) {
63 console.error("Could not write status file " + pidPath, err);
64 return process.exit(1);
65 } else {
66 verification.group = bindExit(function() {
67 fs.unlinkSync(pidPath);
68 return lockfile.unlockSync(lockPath);
69 });
70 return cb(null, verification);
71 }
72 });
73 }
74 });
75 };
76
77 exports.unlock = function(verification) {
78 fs.unlinkSync(verification.pidPath);
79 lockfile.unlockSync(verification.lockPath);
80 return unbindExit(verification.group);
81 };
82
83 exports.find = function(name, configPath, cb) {
84 return findDeep(name, configPath, false, cb);
85 };
86
87 exports.findDeep = findDeep = function(name, configPath, erase, cb) {
88 var lockPath, pidPath;
89 lockPath = path.join(path.dirname(configPath), name + ".lock");
90 pidPath = path.join(path.dirname(configPath), name + ".pid");
91 return fs.exists(lockPath, function(exists) {
92 if (!exists) {
93 return cb(null, false);
94 }
95 return fs.exists(pidPath, function(exists) {
96 if (!exists) {
97 return cb(null, false);
98 }
99 return fs.readFile(pidPath, {
100 encoding: 'utf8'
101 }, function(err, data) {
102 var pidobj;
103 if (err != null) {
104 return cb(err);
105 }
106 pidobj = JSON.parse(data);
107 if (!erase) {
108 return cb(null, true, pidobj);
109 }
110 if (isRunning(pidobj.pid)) {
111 return cb(null, true, pidobj);
112 } else {
113 fs.unlinkSync(pidPath);
114 fs.unlinkSync(lockPath);
115 return cb(null, false);
116 }
117 });
118 });
119 });
120 };
121
122 bindExit = function(fn) {
123 var group, handled;
124 handled = false;
125 group = {
126 fn: fn,
127 exit: function() {
128 if (!handled) {
129 fn();
130 }
131 return handled = true;
132 },
133 sigint: function() {
134 if (!handled) {
135 fn();
136 }
137 handled = true;
138 return process.exit(130);
139 },
140 sigterm: function() {
141 if (!handled) {
142 fn();
143 }
144 handled = true;
145 return process.exit(131);
146 }
147 };
148 process.on('exit', group.exit);
149 process.on('SIGINT', group.sigint);
150 process.on('SIGTERM', group.sigterm);
151 return group;
152 };
153
154 unbindExit = function(group) {
155 process.removeListener('exit', group.exit);
156 process.removeListener('SIGINT', group.sigint);
157 process.removeListener('SIGTERM', group.sigterm);
158 return group;
159 };
160
161}).call(this);