mirror of
https://github.com/telemt/telemt.git
synced 2026-09-18 00:08:32 +03:00
Bridge Request/Buffers/Recovery
Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
@@ -33,10 +33,10 @@ function create(settings){
|
||||
while(attempt<maxAttempts){
|
||||
if(settings.closed()||(external&&external.aborted))throw new Error('request aborted');
|
||||
const remaining=Math.min(deadline-Date.now(),remainingBudget?remainingBudget():Infinity);if(remaining<=0)break;attempt++;
|
||||
const controller=new AbortController(),abort=()=>controller.abort();
|
||||
const controller=new AbortController(),abort=()=>controller.abort();let timedOut=false;
|
||||
if(external)external.addEventListener('abort',abort,{once:true});
|
||||
const requestOptions=Object.assign({},frozenOptions,{signal:controller.signal});
|
||||
const timer=setTimeout(abort,Math.max(1,Math.min(attemptLimit,remaining)));
|
||||
const timer=setTimeout(()=>{timedOut=true;controller.abort()},Math.max(1,Math.min(attemptLimit,remaining)));
|
||||
let response=null,wait=0;
|
||||
try{
|
||||
const fetched=await fetch(settings.origin()+path,requestOptions);
|
||||
@@ -45,12 +45,18 @@ function create(settings){
|
||||
}else{
|
||||
const policy=responsePolicy(path,fetched.status);let body;
|
||||
try{body=await settings.read(fetched,policy.limit,policy.exact,controller.signal)}
|
||||
catch(error){controller.abort();throw settings.failure('protocol',error&&error.message)}
|
||||
catch(error){
|
||||
controller.abort();
|
||||
if(external&&external.aborted)throw error;
|
||||
if(timedOut)throw settings.failure('timeout','response deadline exceeded');
|
||||
throw settings.failure('protocol',error&&error.message);
|
||||
}
|
||||
response={status:fetched.status,headers:fetched.headers,body};return response;
|
||||
}
|
||||
}catch(error){
|
||||
controller.abort();
|
||||
if(settings.closed()||(external&&external.aborted))throw error;
|
||||
if(timedOut)lastReason='timeout';
|
||||
if(settings.reason(error,'')==='protocol')throw error;
|
||||
}finally{clearTimeout(timer);if(external)external.removeEventListener('abort',abort)}
|
||||
const after=Math.min(deadline-Date.now(),remainingBudget?remainingBudget():Infinity);if(attempt>=maxAttempts||after<=0)break;
|
||||
|
||||
@@ -268,6 +268,7 @@ async function runUp(){
|
||||
if(response.headers.get('X-Up-Ack')!==sequence)throw failure('protocol','uplink replay acknowledgement rejected');
|
||||
});
|
||||
if(!recovered||closed||lease.cancelled||sessionToken!==token)return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!settleBatch(lease))return;port.postMessage({t:'traffic',up:lease.total,down:0});upSequence++;lease=null;
|
||||
@@ -421,6 +422,7 @@ async function runLaneUp(lane){
|
||||
if(response.headers.get('X-Up-Ack')!==sequence)throw failure('protocol','lane uplink replay acknowledgement rejected');
|
||||
});
|
||||
if(!recovered||closed||lease.cancelled||sessionToken!==token||lanes.get(lane.id)!==lane)return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!settleBatch(lease))return;port.postMessage({t:'traffic',up:lease.total,down:0});lane.sequence++;lease=null;
|
||||
|
||||
@@ -36,6 +36,9 @@ fn rendered_page_contains_bounded_negotiation_contract() {
|
||||
assert!(page.body.contains("tproxy-auto-v1."));
|
||||
assert!(page.body.contains("tproxy-auto-lane-v1."));
|
||||
assert!(page.body.contains("globalThis.TelemtBridgeResponse"));
|
||||
assert!(page.body.contains("globalThis.TelemtBridgeRequest"));
|
||||
assert!(page.body.contains("globalThis.TelemtBridgeBuffers"));
|
||||
assert!(page.body.contains("globalThis.TelemtBridgeRecovery"));
|
||||
assert!(page.body.contains("responseBody.read"));
|
||||
assert!(!page.body.contains("arrayBuffer()"));
|
||||
assert!(page.body.contains("maxChunks=4096"));
|
||||
@@ -77,13 +80,13 @@ fn rendered_page_embeds_the_configured_bridge_timing_policy() {
|
||||
&SecureRandom::new(),
|
||||
);
|
||||
|
||||
assert!(page.body.contains("const longPollMs=17*1000"));
|
||||
assert!(page.body.contains("let longPollMs=17*1000"));
|
||||
assert!(page.body.contains("bridgeRequestMs=7*1000"));
|
||||
assert!(page.body.contains("bridgeRetryMs=41*1000"));
|
||||
assert!(page.body.contains("bridgeRecoveryMs=13*1000"));
|
||||
assert!(page.body.contains("websocketOpenMs=11*1000"));
|
||||
assert!(page.body.contains("reconnectGraceMs=119*1000"));
|
||||
assert!(page.body.contains("const probeCoalesceMs=4"));
|
||||
assert!(page.body.contains("let probeCoalesceMs=4"));
|
||||
assert!(page.body.contains(
|
||||
"helloTimer=setTimeout(()=>fail('timeout'),bridgeRequestMs)"
|
||||
));
|
||||
@@ -137,12 +140,12 @@ fn retry_and_attempt_state_are_frozen_before_fetch() {
|
||||
let page = render_page("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE", 4);
|
||||
assert!(
|
||||
page.body
|
||||
.contains("async function request(path,frozenOptions,remainingBudget,maxAttempts)")
|
||||
.contains("async function send(path,frozenOptions,remainingBudget,maxAttempts)")
|
||||
);
|
||||
assert!(!page.body.contains("makeOptions"));
|
||||
assert!(
|
||||
page.body
|
||||
.contains("if(closed||(external&&external.aborted))throw new Error('request aborted')")
|
||||
.contains("if(settings.closed()||(external&&external.aborted))throw new Error('request aborted')")
|
||||
);
|
||||
assert!(page.body.contains(
|
||||
"const frozen=options('POST',bootstrap,snapshot.hello,attemptHeaders(snapshot.attempt,snapshot.failure),controller.signal)"
|
||||
|
||||
Reference in New Issue
Block a user