wispjs 2.2.0 → 2.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -88,20 +88,22 @@ export declare class WispSocket {
88
88
  * Performs a git pull operation on the given directory
89
89
  *
90
90
  * @param dir The full directory path to perform a pull on
91
+ * @param timeout In milliseconds, how long to wait before timing out
91
92
  *
92
93
  * @public
93
94
  */
94
- gitPull(dir: string, useAuth?: boolean): Promise<any>;
95
+ gitPull(dir: string, useAuth?: boolean, timeout?: number): Promise<any>;
95
96
  /**
96
97
  * Clones a new Repo to the given directory
97
98
  *
98
99
  * @param url The HTTPS URL of the repository
99
100
  * @param dir The full path of the directory to clone the repository to
100
101
  * @param branch The branch of the repository to clone
102
+ * @param timeout In milliseconds, how long to wait before timing out
101
103
  *
102
104
  * @public
103
105
  */
104
- gitClone(url: string, dir: string, branch: string): Promise<any>;
106
+ gitClone(url: string, dir: string, branch: string, timeout?: number): Promise<any>;
105
107
  /**
106
108
  * Sets up the console listener worker
107
109
  *
@@ -154,7 +156,7 @@ export declare class WispSocket {
154
156
  *
155
157
  * @param nonce The short, unique string that your output will be prefixed with
156
158
  * @param command The full command string to send
157
- * @param timeout How long to wait for output before timing out
159
+ * @param timeout In milliseconds, how long to wait for output before timing out
158
160
  *
159
161
  * @public
160
162
  */
@@ -118,10 +118,11 @@ export class WispSocket {
118
118
  * Performs a git pull operation on the given directory
119
119
  *
120
120
  * @param dir The full directory path to perform a pull on
121
+ * @param timeout In milliseconds, how long to wait before timing out
121
122
  *
122
123
  * @public
123
124
  */
124
- async gitPull(dir, useAuth = false) {
125
+ async gitPull(dir, useAuth = false, timeout = 10000) {
125
126
  await this.verifyPool();
126
127
  const pullResult = await this.pool.run((worker) => {
127
128
  const socket = worker.socket;
@@ -129,7 +130,12 @@ export class WispSocket {
129
130
  logger.log("Running gitPull:", dir);
130
131
  return new Promise((resolve, reject) => {
131
132
  let isPrivate = false;
132
- const finished = (success, output) => {
133
+ let finished;
134
+ const timeoutObj = setTimeout(() => {
135
+ logger.error("Rejected gitPull: 'Timeout'");
136
+ finished(false, "Timeout");
137
+ }, timeout);
138
+ finished = (success, output) => {
133
139
  socket.removeAllListeners("git-pull");
134
140
  socket.removeAllListeners("git-error");
135
141
  socket.removeAllListeners("git-success");
@@ -144,6 +150,7 @@ export class WispSocket {
144
150
  logger.error("Rejected gitPull:", dir, output);
145
151
  reject(output);
146
152
  }
153
+ clearTimeout(timeoutObj);
147
154
  };
148
155
  const sendRequest = (includeAuth = false) => {
149
156
  const data = { dir: dir };
@@ -188,10 +195,11 @@ export class WispSocket {
188
195
  * @param url The HTTPS URL of the repository
189
196
  * @param dir The full path of the directory to clone the repository to
190
197
  * @param branch The branch of the repository to clone
198
+ * @param timeout In milliseconds, how long to wait before timing out
191
199
  *
192
200
  * @public
193
201
  */
194
- async gitClone(url, dir, branch) {
202
+ async gitClone(url, dir, branch, timeout = 20000) {
195
203
  await this.verifyPool();
196
204
  return await this.pool.run((worker) => {
197
205
  const socket = worker.socket;
@@ -199,7 +207,12 @@ export class WispSocket {
199
207
  logger.log("Running gitClone:", url, dir, branch);
200
208
  return new Promise((resolve, reject) => {
201
209
  let isPrivate = false;
202
- const finished = (success, message) => {
210
+ let finished;
211
+ const timeoutObj = setTimeout(() => {
212
+ logger.error("Rejected gitClone: 'Timeout'");
213
+ finished(false, "Timeout");
214
+ }, timeout);
215
+ finished = (success, message) => {
203
216
  socket.removeAllListeners("git-clone");
204
217
  socket.removeAllListeners("git-error");
205
218
  socket.removeAllListeners("git-success");
@@ -213,6 +226,7 @@ export class WispSocket {
213
226
  logger.error("Rejected gitClone:", url, dir, branch, message);
214
227
  reject(message);
215
228
  }
229
+ clearTimeout(timeoutObj);
216
230
  };
217
231
  const sendRequest = (includeAuth = false) => {
218
232
  const data = { dir: dir, url: url, branch: branch };
@@ -333,7 +347,7 @@ export class WispSocket {
333
347
  *
334
348
  * @param nonce The short, unique string that your output will be prefixed with
335
349
  * @param command The full command string to send
336
- * @param timeout How long to wait for output before timing out
350
+ * @param timeout In milliseconds, how long to wait for output before timing out
337
351
  *
338
352
  * @public
339
353
  */
@@ -1,4 +1,9 @@
1
1
  import { Socket } from "socket.io-client";
2
+ type Logger = {
3
+ log(...args: any[]): void;
4
+ error(...args: any[]): void;
5
+ debug(...args: any[]): void;
6
+ };
2
7
  /**
3
8
  * The struct used to define the events that can be sent from the server to the client
4
9
  *
@@ -133,10 +138,8 @@ interface PoolWorker {
133
138
  idx: number;
134
139
  token: string;
135
140
  ready: boolean;
136
- logger: {
137
- log(...args: any[]): void;
138
- error(...args: any[]): void;
139
- };
141
+ done: boolean;
142
+ logger: Logger;
140
143
  }
141
144
  /**
142
145
  * A single Worker within a {@link WebsocketPool}
@@ -147,10 +150,9 @@ interface PoolWorker {
147
150
  */
148
151
  declare class PoolWorker {
149
152
  constructor(pool: WebsocketPool);
150
- available(): boolean;
151
153
  connect(): Promise<void>;
152
154
  disconnect(): Promise<void>;
153
- run(work: (worker: PoolWorker) => Promise<any>): Promise<any>;
155
+ private processWork;
154
156
  }
155
157
  /**
156
158
  * Struct used to manage a pool of WebSocket workers
@@ -160,6 +162,7 @@ export interface WebsocketPool {
160
162
  token: string;
161
163
  url: string;
162
164
  maxWorkers: number;
165
+ logger: Logger;
163
166
  queue: ((worker: PoolWorker) => Promise<any>)[];
164
167
  }
165
168
  /**
@@ -175,9 +178,8 @@ export interface WebsocketPool {
175
178
  */
176
179
  export declare class WebsocketPool {
177
180
  constructor(url: string, token: string);
178
- createWorker(): Promise<PoolWorker>;
181
+ getWork(): ((worker: PoolWorker) => Promise<any>) | undefined;
179
182
  disconnect(): Promise<void>;
180
- processQueue(): Promise<any>;
181
183
  run(work: (worker: PoolWorker) => Promise<any>): Promise<any>;
182
184
  }
183
185
  export {};
@@ -1,4 +1,5 @@
1
1
  import { io } from "socket.io-client";
2
+ const WISP_DEBUG = process.env.WISP_DEBUG === "true";
2
3
  /**
3
4
  * A single Worker within a {@link WebsocketPool}
4
5
  *
@@ -10,6 +11,7 @@ class PoolWorker {
10
11
  constructor(pool) {
11
12
  this.pool = pool;
12
13
  this.ready = false;
14
+ this.done = false;
13
15
  this.idx = pool.workers.length;
14
16
  this.token = pool.token;
15
17
  this.socket = io(pool.url, {
@@ -22,10 +24,13 @@ class PoolWorker {
22
24
  this.logger = {
23
25
  log: (...args) => console.log(logPrefix, args),
24
26
  error: (...args) => console.error(logPrefix, args),
27
+ debug: (...args) => {
28
+ if (!WISP_DEBUG)
29
+ return;
30
+ console.debug(logPrefix, args);
31
+ }
25
32
  };
26
- }
27
- available() {
28
- return this.ready && this.socket.connected;
33
+ this.connect().then(() => this.processWork()).catch(err => this.logger.error(err));
29
34
  }
30
35
  connect() {
31
36
  const socket = this.socket;
@@ -33,12 +38,9 @@ class PoolWorker {
33
38
  socket.onAnyOutgoing(this.logger.log);
34
39
  logger.log("Connecting to websocket...");
35
40
  return new Promise((resolve, reject) => {
36
- let connectedOnce = false;
37
41
  const timeout = setTimeout(() => {
38
- if (!connectedOnce) {
39
- logger.error("Socket didn't connect in time");
40
- reject("Connection Timeout");
41
- }
42
+ logger.error("Socket didn't connect in time");
43
+ reject("Connection Timeout");
42
44
  }, 10000);
43
45
  socket.on("connect", () => {
44
46
  logger.log("Connected to WebSocket");
@@ -50,23 +52,18 @@ class PoolWorker {
50
52
  });
51
53
  socket.on("connect_error", (error) => {
52
54
  logger.error(`WebSocket Connect error: ${error.toString()}`);
53
- if (!connectedOnce) {
54
- connectedOnce = true;
55
- clearTimeout(timeout);
56
- reject(`Connection error: ${error.toString()}`);
57
- }
55
+ this.done = true;
56
+ clearTimeout(timeout);
57
+ reject(`Connection error: ${error.toString()}`);
58
58
  });
59
59
  socket.on("disconnect", (reason) => {
60
60
  logger.log(`Disconnected from WebSocket: ${reason}`);
61
61
  });
62
62
  socket.on("auth_success", () => {
63
63
  logger.log("Auth success");
64
- if (!connectedOnce) {
65
- connectedOnce = true;
66
- this.ready = true;
67
- clearTimeout(timeout);
68
- resolve();
69
- }
64
+ this.ready = true;
65
+ clearTimeout(timeout);
66
+ resolve();
70
67
  });
71
68
  socket.connect();
72
69
  });
@@ -79,25 +76,38 @@ class PoolWorker {
79
76
  reject();
80
77
  }, 5000);
81
78
  this.socket.once("disconnect", () => {
79
+ this.done = true;
82
80
  clearTimeout(timeout);
83
81
  resolve();
84
82
  });
85
83
  this.socket.disconnect();
86
84
  });
87
85
  }
88
- async run(work) {
89
- this.ready = false;
90
- // TODO: Verify that a finally is what we want here
91
- try {
92
- return await work(this);
93
- }
94
- catch (e) {
95
- this.logger.error(e);
96
- throw e;
97
- }
98
- finally {
99
- this.ready = true;
100
- this.pool.processQueue();
86
+ async processWork() {
87
+ while (!this.done) {
88
+ if (!this.ready) {
89
+ await new Promise(resolve => setTimeout(resolve, 100));
90
+ continue;
91
+ }
92
+ const work = this.pool.getWork();
93
+ if (work) {
94
+ this.ready = false;
95
+ try {
96
+ this.logger.debug("Running my work");
97
+ await work(this);
98
+ this.logger.debug("Done with my work, ready for more");
99
+ }
100
+ catch (e) {
101
+ this.logger.error("Failed to run work");
102
+ this.logger.error(e);
103
+ }
104
+ finally {
105
+ this.ready = true;
106
+ }
107
+ }
108
+ else {
109
+ await new Promise(resolve => setTimeout(resolve, 100));
110
+ }
101
111
  }
102
112
  }
103
113
  }
@@ -114,44 +124,34 @@ class PoolWorker {
114
124
  */
115
125
  export class WebsocketPool {
116
126
  constructor(url, token) {
117
- this.maxWorkers = 5;
127
+ const envMaxWorkers = process.env.WISP_MAX_WORKERS;
128
+ this.maxWorkers = envMaxWorkers ? parseInt(envMaxWorkers) : 5;
118
129
  this.token = token;
119
130
  this.url = url;
131
+ const logPrefix = "[Pool]";
132
+ this.logger = {
133
+ log: (...args) => console.log(logPrefix, args),
134
+ error: (...args) => console.error(logPrefix, args),
135
+ debug: (...args) => {
136
+ if (!WISP_DEBUG)
137
+ return;
138
+ console.debug(logPrefix, args);
139
+ }
140
+ };
120
141
  this.workers = [];
121
142
  this.queue = [];
143
+ this.logger.log(`Creating a new Pool with ${this.maxWorkers} workers`);
144
+ for (let i = 0; i < this.maxWorkers; i++) {
145
+ this.workers.push(new PoolWorker(this));
146
+ }
122
147
  }
123
- async createWorker() {
124
- console.log("Creating a new Pool worker");
125
- const worker = new PoolWorker(this);
126
- this.workers.push(worker);
127
- await worker.connect();
128
- return worker;
148
+ getWork() {
149
+ return this.queue.shift();
129
150
  }
130
151
  async disconnect() {
152
+ this.logger.log("Disconnecting all workers...");
131
153
  await Promise.all(this.workers.map((worker) => worker.disconnect()));
132
- }
133
- async processQueue() {
134
- if (this.queue.length == 0) {
135
- return;
136
- }
137
- const work = this.queue.shift();
138
- if (!work) {
139
- return;
140
- }
141
- let worker;
142
- if (this.workers.length == 0) {
143
- worker = await this.createWorker();
144
- }
145
- worker = worker || this.workers.find((worker) => worker.available());
146
- if (!worker) {
147
- if (this.workers.length < this.maxWorkers) {
148
- worker = await this.createWorker();
149
- }
150
- else {
151
- return;
152
- }
153
- }
154
- return await worker.run(work);
154
+ this.logger.log("All workers disconnected");
155
155
  }
156
156
  async run(work) {
157
157
  return new Promise(async (resolve, reject) => {
@@ -165,7 +165,6 @@ export class WebsocketPool {
165
165
  reject(e);
166
166
  }
167
167
  });
168
- return this.processQueue();
169
168
  });
170
169
  }
171
170
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wispjs",
3
- "version": "2.2.0",
3
+ "version": "2.3.4",
4
4
  "type": "module",
5
5
  "description": "A package for interacting with Wisp-based server panels",
6
6
  "main": "dist/wisp.js",