Skip to content

Commit

Permalink
Do a dance to handle the docker "hijack" message
Browse files Browse the repository at this point in the history
  • Loading branch information
blast-hardcheese committed Nov 15, 2024
1 parent 9364f13 commit 4e57c85
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
19 changes: 18 additions & 1 deletion impls/node-protocolv2/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,24 @@ const handles = new Map<
>();

for await (const line of rl) {
const { id, init, payload, proc } = JSON.parse(line);
const { id, init, payload, proc } = (() => {
try {
return JSON.parse(line);
} catch (e) {
// Sometimes docker injects this into the stream:
// {"hijack":true,"stream":true,"stdin":true,"stdout":true,"stderr":true}{"type": "invoke", ...
const match = e.message.match(/line (\d*) column (\d*)/);
if (!!match) {
const offset = parseInt(match['2'], 10);
const first = JSON.parse(line.substring(0, offset));
assert(
'hijack' in first,
'The only syntax errors that we expect are that Docker jams stuff into the stream',
);
return JSON.parse(line.substring(offset));
}
}
})();

switch (proc) {
case 'kv.set': {
Expand Down
19 changes: 18 additions & 1 deletion impls/node/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,24 @@ const rl = readline.createInterface({

const handles = new Map<string, Pushable<unknown>>();
for await (const line of rl) {
const { id, init, payload, proc } = JSON.parse(line);
const { id, init, payload, proc } = (() => {
try {
return JSON.parse(line);
} catch (e) {
// Sometimes docker injects this into the stream:
// {"hijack":true,"stream":true,"stdin":true,"stdout":true,"stderr":true}{"type": "invoke", ...
const match = e.message.match(/line (\d*) column (\d*)/);
if (!!match) {
const offset = parseInt(match['2'], 10);
const first = JSON.parse(line.substring(0, offset));
assert(
'hijack' in first,
'The only syntax errors that we expect are that Docker jams stuff into the stream',
);
return JSON.parse(line.substring(offset));
}
}
})();

switch (proc) {
case 'kv.set': {
Expand Down
11 changes: 10 additions & 1 deletion impls/python/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,16 @@ async def process_commands():
if not line:
break

action = json.loads(line)
try:
action = json.loads(line)
except json.JSONDecodeError as e:
# Sometimes docker injects this into the stream:
# {"hijack":true,"stream":true,"stdin":true,"stdout":true,"stderr":true}{"type": "invoke", ...
offset = e.colno - 1
first = json.loads(line[0:offset])
assert "hijack" in first
action = json.loads(line[offset:])

if not action:
print("FATAL: invalid command", line)
sys.exit(1)
Expand Down

0 comments on commit 4e57c85

Please sign in to comment.