@output.ai/core 0.4.2 → 0.4.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/package.json
CHANGED
|
@@ -5,16 +5,19 @@ import { EOL } from 'node:os';
|
|
|
5
5
|
|
|
6
6
|
const oneMonthInSeconds = 60 * 60 * 24 * 30;
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const addEntry = async ( { entry, executionContext: { workflowName, workflowId } } ) => {
|
|
9
9
|
const key = `traces/${workflowName}/${workflowId}`;
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
const client = await getRedisClient();
|
|
11
|
+
await client.multi()
|
|
12
|
+
.zAdd( key, [ { score: entry.timestamp, value: JSON.stringify( entry ) } ], { NX: true } )
|
|
13
|
+
.expire( key, oneMonthInSeconds, 'GT' )
|
|
14
|
+
.exec();
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const getAllEntries = async ( { workflowName, workflowId } ) => {
|
|
18
|
+
const key = `traces/${workflowName}/${workflowId}`;
|
|
19
|
+
const client = await getRedisClient();
|
|
20
|
+
const zList = await client.zRange( key, 0, -1 );
|
|
18
21
|
return zList.map( v => JSON.parse( v ) );
|
|
19
22
|
};
|
|
20
23
|
|
|
@@ -41,13 +44,19 @@ export const init = async () => {
|
|
|
41
44
|
*/
|
|
42
45
|
export const exec = async ( { entry, executionContext } ) => {
|
|
43
46
|
const { workflowName, workflowId, startTime } = executionContext;
|
|
44
|
-
|
|
47
|
+
|
|
48
|
+
await addEntry( { entry, executionContext } );
|
|
45
49
|
|
|
46
50
|
const isRootWorkflowEnd = !entry.parentId && entry.phase !== 'start';
|
|
47
|
-
|
|
51
|
+
if ( !isRootWorkflowEnd ) {
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const content = buildTraceTree( await getAllEntries( { workflowName, workflowId } ) );
|
|
56
|
+
return upload( {
|
|
48
57
|
key: getS3Key( { workflowId, workflowName, startTime } ),
|
|
49
58
|
content: JSON.stringify( content, undefined, 2 ) + EOL
|
|
50
|
-
} )
|
|
59
|
+
} );
|
|
51
60
|
};
|
|
52
61
|
|
|
53
62
|
/**
|
|
@@ -3,10 +3,10 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
3
3
|
const redisMulti = {
|
|
4
4
|
zAdd: vi.fn().mockReturnThis(),
|
|
5
5
|
expire: vi.fn().mockReturnThis(),
|
|
6
|
-
zRange: vi.fn().mockReturnThis(),
|
|
7
6
|
exec: vi.fn()
|
|
8
7
|
};
|
|
9
|
-
const
|
|
8
|
+
const zRangeMock = vi.fn();
|
|
9
|
+
const getRedisClientMock = vi.fn( async () => ( { multi: () => redisMulti, zRange: zRangeMock } ) );
|
|
10
10
|
vi.mock( './redis_client.js', () => ( { getRedisClient: getRedisClientMock } ) );
|
|
11
11
|
|
|
12
12
|
const uploadMock = vi.fn();
|
|
@@ -32,18 +32,15 @@ describe( 'tracing/processors/s3', () => {
|
|
|
32
32
|
const startTime = Date.parse( '2020-01-02T03:04:05.678Z' );
|
|
33
33
|
const ctx = { executionContext: { workflowId: 'id1', workflowName: 'WF', startTime } };
|
|
34
34
|
|
|
35
|
-
//
|
|
36
|
-
redisMulti.exec
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
.
|
|
43
|
-
|
|
44
|
-
JSON.stringify( { name: 'A', phase: 'tick', timestamp: startTime + 1 } ),
|
|
45
|
-
JSON.stringify( { name: 'A', phase: 'end', timestamp: startTime + 2 } )
|
|
46
|
-
] ] );
|
|
35
|
+
// multi().exec() just needs to resolve for addEntry calls
|
|
36
|
+
redisMulti.exec.mockResolvedValue( [] );
|
|
37
|
+
|
|
38
|
+
// zRange is only called once at the end to get all entries
|
|
39
|
+
zRangeMock.mockResolvedValue( [
|
|
40
|
+
JSON.stringify( { name: 'A', phase: 'start', timestamp: startTime } ),
|
|
41
|
+
JSON.stringify( { name: 'A', phase: 'tick', timestamp: startTime + 1 } ),
|
|
42
|
+
JSON.stringify( { name: 'A', phase: 'end', timestamp: startTime + 2 } )
|
|
43
|
+
] );
|
|
47
44
|
|
|
48
45
|
await exec( { ...ctx, entry: { name: 'A', phase: 'start', timestamp: startTime, parentId: 'root' } } );
|
|
49
46
|
await exec( { ...ctx, entry: { name: 'A', phase: 'tick', timestamp: startTime + 1, parentId: 'root' } } );
|
|
@@ -52,7 +49,10 @@ describe( 'tracing/processors/s3', () => {
|
|
|
52
49
|
|
|
53
50
|
// Accumulation happened 3 times
|
|
54
51
|
expect( redisMulti.zAdd ).toHaveBeenCalledTimes( 3 );
|
|
55
|
-
|
|
52
|
+
|
|
53
|
+
// Tree is only built once at the end (not on every event)
|
|
54
|
+
expect( buildTraceTreeMock ).toHaveBeenCalledTimes( 1 );
|
|
55
|
+
expect( zRangeMock ).toHaveBeenCalledTimes( 1 );
|
|
56
56
|
|
|
57
57
|
// Only last call triggers upload
|
|
58
58
|
expect( uploadMock ).toHaveBeenCalledTimes( 1 );
|