geonix 1.9.0 → 1.10.3
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.
- package/.vscode/settings.json +1 -1
- package/exports.js +3 -1
- package/package.json +1 -1
- package/src/Service.js +11 -2
- package/src/Stream.js +9 -2
- package/test/.env +0 -1
- package/test/classes.js +0 -0
- package/test/inheritance.js +0 -60
- package/test/package.json +0 -18
- package/test/private.js +0 -31
- package/test/registration.js +0 -36
- package/test/shitstorm.js +0 -43
- package/test/stream.js +0 -38
- package/test/stream2.js +0 -42
package/.vscode/settings.json
CHANGED
package/exports.js
CHANGED
|
@@ -38,4 +38,6 @@ export { connection, stopConnection } from './src/Connection.js'
|
|
|
38
38
|
export { registry } from './src/Registry.js'
|
|
39
39
|
export { Request, Subscribe, Publish } from './src/Request.js'
|
|
40
40
|
export { RequestOptions } from './src/RequestOptions.js'
|
|
41
|
-
export { picoid as randomID } from './src/Util.js'
|
|
41
|
+
export { picoid as randomID } from './src/Util.js'
|
|
42
|
+
|
|
43
|
+
export { stats as StreamStats } from './src/Stream.js'
|
package/package.json
CHANGED
package/src/Service.js
CHANGED
|
@@ -70,6 +70,12 @@ export class Service {
|
|
|
70
70
|
a: webserver.getAddresses().map(address => `${address}:${webserver.getPort()}`)
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// check if method takes context as first argument
|
|
74
|
+
for (let methodName of this.#me.m) {
|
|
75
|
+
const method = this[methodName]
|
|
76
|
+
method.takesContext = method.toString()?.match(/\((?<args>.*)\)/)?.groups?.args.startsWith('$')
|
|
77
|
+
}
|
|
78
|
+
|
|
73
79
|
this.#beacon()
|
|
74
80
|
this.#queueListener()
|
|
75
81
|
this.#directListener()
|
|
@@ -193,8 +199,11 @@ export class Service {
|
|
|
193
199
|
return respond({ e: `unknown method (${this.#me.n}.${methodName})` })
|
|
194
200
|
|
|
195
201
|
try {
|
|
196
|
-
|
|
197
|
-
|
|
202
|
+
// inject context as first argument
|
|
203
|
+
if (method.takesContext)
|
|
204
|
+
_args = [OverlayObject(context, { caller, me: this.#me }), ..._args]
|
|
205
|
+
|
|
206
|
+
respond({ r: await method.apply(this, _args) })
|
|
198
207
|
} catch (e) {
|
|
199
208
|
respond({ e: `${EOL}${ERROR_BEGIN_DELIMITER} ${this.#me.n}${EOL}${e.stack}${EOL}${ERROR_END_DELIMITER}` })
|
|
200
209
|
}
|
package/src/Stream.js
CHANGED
|
@@ -4,6 +4,8 @@ import { picoid, StreamChunker } from './Util.js'
|
|
|
4
4
|
|
|
5
5
|
const CHUNK_SIZE = 1024 * 128
|
|
6
6
|
|
|
7
|
+
export const stats = {}
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* Converts data to stream
|
|
9
11
|
*
|
|
@@ -11,7 +13,7 @@ const CHUNK_SIZE = 1024 * 128
|
|
|
11
13
|
* @param {*} automated
|
|
12
14
|
* @returns
|
|
13
15
|
*/
|
|
14
|
-
export function Stream(data) {
|
|
16
|
+
export function Stream(data, tag = '_') {
|
|
15
17
|
if (isStream(data))
|
|
16
18
|
return data
|
|
17
19
|
|
|
@@ -27,13 +29,18 @@ export function Stream(data) {
|
|
|
27
29
|
readable.pipe(transform)
|
|
28
30
|
readable = transform
|
|
29
31
|
|
|
32
|
+
stats[tag] = stats[tag] !== undefined ? stats[tag] + 1 : 1
|
|
33
|
+
|
|
30
34
|
const controlHandler = async () => {
|
|
31
35
|
const control = await connection.subscribe(`gx2.stream.${id}.a`, { max: 1 })
|
|
32
36
|
|
|
33
37
|
for await (const event of control)
|
|
34
38
|
if (event.data.length === 0) {
|
|
35
39
|
readable.on('data', chunk => connection.publishRaw(`gx2.stream.${id}.b`, chunk))
|
|
36
|
-
readable.on('close', () =>
|
|
40
|
+
readable.on('close', () => {
|
|
41
|
+
connection.publishRaw(`gx2.stream.${id}.b`)
|
|
42
|
+
stats[tag]--
|
|
43
|
+
})
|
|
37
44
|
}
|
|
38
45
|
}
|
|
39
46
|
|
package/test/.env
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
TRANSPORT=nats://phobos.tria.hr:4222
|
package/test/classes.js
DELETED
|
File without changes
|
package/test/inheritance.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { Service, Remote } from 'geonix'
|
|
2
|
-
|
|
3
|
-
const calc = Remote('Calculator')
|
|
4
|
-
const tp = Remote('TimeProvider')
|
|
5
|
-
|
|
6
|
-
class Logger {
|
|
7
|
-
|
|
8
|
-
constructor(prefix) {
|
|
9
|
-
this.prefix = prefix
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
log(...args) {
|
|
13
|
-
console.log(`${new Date().toISOString()}|${this.prefix}|`, ...args)
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class BaseService extends Service {
|
|
18
|
-
|
|
19
|
-
logger = new Logger(this.constructor.name)
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class CalculatorRepository {
|
|
25
|
-
|
|
26
|
-
constructor(service) {
|
|
27
|
-
this.logger = service.logger
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async getCurrentTime() {
|
|
31
|
-
this.logger.log('getCurrentTime')
|
|
32
|
-
return await Remote('TimeProvider').now()
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
class Calculator extends BaseService {
|
|
38
|
-
|
|
39
|
-
repo = new CalculatorRepository(this)
|
|
40
|
-
|
|
41
|
-
async onStart() {
|
|
42
|
-
this.logger.log('current time =', await this.repo.getCurrentTime())
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
thisHere() {
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
class TimeProvider extends BaseService {
|
|
52
|
-
|
|
53
|
-
now() {
|
|
54
|
-
return new Date().toISOString()
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
Calculator.start()
|
|
60
|
-
TimeProvider.start()
|
package/test/package.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "test",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "stream.js",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
9
|
-
},
|
|
10
|
-
"keywords": [],
|
|
11
|
-
"author": "",
|
|
12
|
-
"license": "ISC",
|
|
13
|
-
"dependencies": {
|
|
14
|
-
"dotenv": "^16.3.1",
|
|
15
|
-
"geonix": "file:..",
|
|
16
|
-
"nats": "^2.16.0"
|
|
17
|
-
}
|
|
18
|
-
}
|
package/test/private.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export const OverlayObject = (object, overlay) => {
|
|
2
|
-
return new Proxy(object, {
|
|
3
|
-
get: (t, p) => overlay[p] !== undefined ? overlay[p] : t[p]
|
|
4
|
-
}
|
|
5
|
-
)
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
class Test {
|
|
9
|
-
|
|
10
|
-
#me = { works: true }
|
|
11
|
-
|
|
12
|
-
get me() { return this.#me }
|
|
13
|
-
|
|
14
|
-
external() {
|
|
15
|
-
return this.me
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
call(method) {
|
|
19
|
-
try {
|
|
20
|
-
const methodContext = { context: 'this is context value' }
|
|
21
|
-
const $context = OverlayObject(this, methodContext)
|
|
22
|
-
return instance[method].apply($context)
|
|
23
|
-
} catch (e) {
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const instance = new Test()
|
|
30
|
-
|
|
31
|
-
console.log(instance.call('external'))
|
package/test/registration.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Service, Remote, registry } from '../exports.js'
|
|
2
|
-
import { sleep } from '../src/Util.js'
|
|
3
|
-
|
|
4
|
-
class BaseService extends Service {
|
|
5
|
-
|
|
6
|
-
static start(options = {}) {
|
|
7
|
-
super.start({
|
|
8
|
-
...options,
|
|
9
|
-
handlers: {
|
|
10
|
-
before: [
|
|
11
|
-
(req, res, next) => {
|
|
12
|
-
console.log('before')
|
|
13
|
-
next()
|
|
14
|
-
}
|
|
15
|
-
],
|
|
16
|
-
after: [(error, req, res, next) => {
|
|
17
|
-
if (error) {
|
|
18
|
-
res.send({ status: 'rawr', error: error.message })
|
|
19
|
-
}
|
|
20
|
-
}]
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
class First extends BaseService {
|
|
28
|
-
|
|
29
|
-
'GET /wow'(req, res) {
|
|
30
|
-
throw Error('wow')
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
First.start()
|
package/test/shitstorm.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'fs/promises';
|
|
2
|
-
import { Service, Stream, getReadable } from '../exports.js';
|
|
3
|
-
|
|
4
|
-
process.env.LOCAL_PORT = 1234
|
|
5
|
-
|
|
6
|
-
class DownloadServiceDebuggingSession extends Service {
|
|
7
|
-
|
|
8
|
-
#transferCounter = 1
|
|
9
|
-
|
|
10
|
-
onStart() {
|
|
11
|
-
console.log("Starting service...");
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
'GET /api/download/local' = [
|
|
15
|
-
async (_, res) => {
|
|
16
|
-
const id = this.#transferCounter++
|
|
17
|
-
|
|
18
|
-
console.log(`transfer=${id} begin`)
|
|
19
|
-
const result = await this.getLocalFile()
|
|
20
|
-
console.log(`transfer=${id} stream=${JSON.stringify(result)}`)
|
|
21
|
-
const stream = await getReadable(result)
|
|
22
|
-
console.log(`transfer=${id}`)
|
|
23
|
-
stream.pipe(res)
|
|
24
|
-
|
|
25
|
-
let counter = 0;
|
|
26
|
-
stream.on('data', (chunk) => {
|
|
27
|
-
counter += chunk.length
|
|
28
|
-
// console.log(`transfer=${id} sent=${(counter / 1024 / 1024).toFixed(2).padStart()}`)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
stream.on('end', () => {
|
|
32
|
-
console.log(`transfer=${id} end`)
|
|
33
|
-
})
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
|
|
37
|
-
getLocalFile = async () => {
|
|
38
|
-
const buffer = await readFile("./test150.txt")
|
|
39
|
-
return Stream(buffer)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
DownloadServiceDebuggingSession.start()
|
package/test/stream.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { randomBytes } from 'node:crypto'
|
|
2
|
-
import { Stream, getReadable, connection } from 'geonix'
|
|
3
|
-
import { createWriteStream, readFileSync } from 'node:fs'
|
|
4
|
-
import { createHash } from 'node:crypto'
|
|
5
|
-
import { pipeline } from 'node:stream/promises'
|
|
6
|
-
|
|
7
|
-
await connection.waitUntilReady()
|
|
8
|
-
|
|
9
|
-
const hash = data => createHash('sha512').update(data).digest('base64')
|
|
10
|
-
|
|
11
|
-
const PAYLOAD_SIZE = 1024 * 1024 * 10
|
|
12
|
-
const TEMP_FILE = '/tmp/geonix.stream_test'
|
|
13
|
-
|
|
14
|
-
console.time('test')
|
|
15
|
-
try {
|
|
16
|
-
const payload = randomBytes(PAYLOAD_SIZE)
|
|
17
|
-
const sourceHash = hash(payload)
|
|
18
|
-
|
|
19
|
-
const source = await getReadable(Stream(payload))
|
|
20
|
-
const dest = createWriteStream(TEMP_FILE)
|
|
21
|
-
|
|
22
|
-
await pipeline(source, dest)
|
|
23
|
-
|
|
24
|
-
const check = readFileSync(TEMP_FILE)
|
|
25
|
-
const destHash = hash(check)
|
|
26
|
-
|
|
27
|
-
if (sourceHash == destHash) {
|
|
28
|
-
console.log('MATCH')
|
|
29
|
-
} else {
|
|
30
|
-
console.error('Destination does not match the source!')
|
|
31
|
-
console.log(payload)
|
|
32
|
-
console.log(check)
|
|
33
|
-
}
|
|
34
|
-
} catch (e) {
|
|
35
|
-
console.error(e)
|
|
36
|
-
} finally {
|
|
37
|
-
console.timeEnd('test')
|
|
38
|
-
}
|
package/test/stream2.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import 'dotenv/config'
|
|
2
|
-
import { randomBytes } from 'node:crypto'
|
|
3
|
-
import { Stream, Remote, getReadable, connection, Service, streamToBuffer } from 'geonix'
|
|
4
|
-
import { createWriteStream, readFileSync } from 'node:fs'
|
|
5
|
-
import { createHash } from 'node:crypto'
|
|
6
|
-
import { pipeline } from 'node:stream/promises'
|
|
7
|
-
|
|
8
|
-
const hash = data => createHash('sha256').update(data).digest('base64')
|
|
9
|
-
const self = Remote('StreamTest')
|
|
10
|
-
|
|
11
|
-
class StreamTest extends Service {
|
|
12
|
-
|
|
13
|
-
async onStart() {
|
|
14
|
-
const perform = async (n) => {
|
|
15
|
-
const fileName = `${n}.random`
|
|
16
|
-
const { checksum, stream } = await self.readFile(fileName)
|
|
17
|
-
const data = await streamToBuffer(stream)
|
|
18
|
-
const verification = hash(data)
|
|
19
|
-
|
|
20
|
-
console.log(`${fileName} - ${data.length} bytes - ${checksum === verification}`)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const jobs = []
|
|
24
|
-
for (let n = 0; n < 1024; n++)
|
|
25
|
-
jobs.push(perform(n))
|
|
26
|
-
|
|
27
|
-
await Promise.all(jobs)
|
|
28
|
-
|
|
29
|
-
console.log('done')
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async readFile(fileName, size = 1024 * Math.round(Math.random() * 1024)) {
|
|
33
|
-
const bytes = randomBytes(size)
|
|
34
|
-
const checksum = hash(bytes)
|
|
35
|
-
|
|
36
|
-
return { checksum, stream: Stream(bytes) }
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
StreamTest.start()
|