-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample.js
More file actions
146 lines (143 loc) · 4.13 KB
/
Copy pathexample.js
File metadata and controls
146 lines (143 loc) · 4.13 KB
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// @ts-check
const yargs = require('yargs')
const { GhkvDataStore } = require('./lib')
const { GhkvResourceLock } = require('./lib/contrib/resource-lock')
const os = require('os')
const execa = require('execa')
const expect = require('expect')
function createStore() {
const store = new GhkvDataStore({
owner: 'taskworld',
repo: 'ghkv',
branch: 'datastore',
accessToken: process.env.GITHUB_TOKEN,
})
return store
}
yargs
.demandCommand()
.strict()
.help()
.command(
'get <key>',
'Get data from the datastore',
{ key: { type: 'string' } },
async (args) => {
const store = createStore()
const doc = store.doc(args.key)
const result = await doc.get()
console.log(JSON.stringify(result, null, 2))
}
)
.command(
'set <key> <value>',
'Set data to the datastore',
{ key: { type: 'string' }, value: { type: 'string' } },
async (args) => {
const store = createStore()
const doc = store.doc(args.key)
const result = await doc.set(JSON.parse(args.value))
console.log(JSON.stringify(result, null, 2))
}
)
.command('test:counter', 'Test basic optimistic locking', {}, async () => {
const store = createStore()
const doc = store.doc('examples/counter')
await doc.set({ count: 0 }, { message: `Reset counter ${by()}` })
if (process.env.GHKV_EXAMPLE_TEST_COUNTER_MODE === 'concurrently') {
await execa('node', ['example', 'test:counter:increment-concurrently'], {
stdio: 'inherit',
})
} else {
await Promise.all([
execa('node', ['example', 'test:counter:increment-single'], {
stdio: 'inherit',
}),
execa('node', ['example', 'test:counter:increment-single'], {
stdio: 'inherit',
}),
execa('node', ['example', 'test:counter:increment-single'], {
stdio: 'inherit',
}),
])
}
expect((await doc.get()).count).toBe(3)
})
.command(
'test:counter:increment-single',
'Add to a shared counter',
{},
async () => {
const store = createStore()
const doc = store.doc('examples/counter')
const result = await doc.update(
(item = {}) => {
return { ...item, count: (+item.count || 0) + 1 }
},
{ message: `Increment counter ${by()}` }
)
console.log(JSON.stringify(result, null, 2))
}
)
.command(
'test:counter:increment-concurrently',
'Add to a shared counter',
{},
async () => {
const store = createStore()
const doc = store.doc('examples/counter')
const updateFn = (item = {}) => {
return { ...item, count: (+item.count || 0) + 1 }
}
const result = await Promise.all([
doc.update(updateFn, {
message: `Increment counter ${by('1')}`,
}),
doc.update(updateFn, {
message: `Increment counter ${by('2')}`,
}),
doc.update(updateFn, {
message: `Increment counter ${by('3')}`,
}),
])
console.log(JSON.stringify(result, null, 2))
}
)
.command(
'test:counter-queue',
'Test queueing up to test the counter',
{},
async (args) => {
const store = createStore()
const lock = new GhkvResourceLock(store, 'examples/counter-lock')
const acquiredLock = await lock.acquire(
[process.env.GITHUB_RUN_ID, os.hostname(), process.pid].join('-')
)
try {
await execa('node', ['example', 'test:counter'], { stdio: 'inherit' })
} finally {
await acquiredLock.release()
}
}
)
.command(
'test',
'Test running multiple multiple tests that has a shared critical section',
{},
async () => {
await Promise.all([
execa('node', ['example', 'test:counter-queue'], {
stdio: 'inherit',
env: { GHKV_EXAMPLE_TEST_COUNTER_MODE: 'normal' },
}),
execa('node', ['example', 'test:counter-queue'], {
stdio: 'inherit',
env: { GHKV_EXAMPLE_TEST_COUNTER_MODE: 'concurrently' },
}),
])
}
)
.parse()
function by(suffix = '') {
return `by ${os.hostname()}/${process.pid}${suffix ? ` (${suffix})` : ''}`
}