eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 2.57 kB
JavaScript
import{createLogger,formatError}from"#internal/logging.js";import{TraceFlags,context,createContextKey}from"#compiled/@opentelemetry/api/index.js";const log=createLogger(`harness.batch-span-processor`),SUPPRESS_TRACING_KEY=createContextKey(`OpenTelemetry SDK Context Key SUPPRESS_TRACING`),DEFAULTS={exportTimeoutMillis:3e4,maxExportBatchSize:512,maxQueueSize:2048,scheduledDelayMillis:5e3};function batchSpanProcessor(e,t={}){let n=t.exportTimeoutMillis??DEFAULTS.exportTimeoutMillis,r=t.maxExportBatchSize??DEFAULTS.maxExportBatchSize,i=t.maxQueueSize??DEFAULTS.maxQueueSize,a=t.scheduledDelayMillis??DEFAULTS.scheduledDelayMillis,o=[],s,c=Promise.resolve(),l=!1;function cancelTimer(){s!==void 0&&(clearTimeout(s),s=void 0)}function scheduleDrain(){s===void 0&&(s=setTimeout(()=>{s=void 0,drain()},a),s.unref?.())}function drain(){return waitForExporter(pendingDrain(),`span export`).then(()=>void 0)}async function exportBatch(t){try{await new Promise((n,r)=>{try{context.with(context.active().setValue(SUPPRESS_TRACING_KEY,!0),()=>{e.export(t,e=>{if(e.code===0){n();return}r(e.error??Error(`Span export failed.`))})})}catch(e){r(e instanceof Error?e:Error(String(e)))}})}catch(e){log.warn(`span export failed`,{error:formatError(e)})}}return{async forceFlush(){!l&&await waitForExporter(pendingDrain(),`span export`)&&e.forceFlush!==void 0&&await waitForExporter(settleExporter(`exporter flush`,e.forceFlush),`exporter flush`)},onEnd(e){if(!l&&isSampled(e)&&!(o.length>=i)){if(o.push(e),o.length>=r){drain();return}scheduleDrain()}},onStart(){},async shutdown(){l=!0;let t=pendingDrain();if(!await waitForExporter(t,`span export`)){t.then(()=>settleExporter(`exporter shutdown`,e.shutdown));return}await waitForExporter(settleExporter(`exporter shutdown`,e.shutdown),`exporter shutdown`)}};function pendingDrain(){return cancelTimer(),c=c.then(async()=>{for(;o.length>0;)await exportBatch(o.splice(0,r))}),c}async function waitForExporter(e,t){let r,i=new Promise(e=>{r=setTimeout(()=>{log.warn(`${t} timed out; preserving exporter serialization`,{timeoutMillis:n}),e(!1)},n),r.unref?.()}),a=e.then(()=>!0);try{return await Promise.race([a,i])}finally{clearTimeout(r)}}async function settleExporter(t,n){try{await n.call(e)}catch(e){log.warn(`${t} failed`,{error:formatError(e)})}}}function isSampled(e){if(typeof e!=`object`||!e||!(`spanContext`in e))return!1;let t=e.spanContext;if(typeof t!=`function`)return!1;let n=Reflect.apply(t,e,[]);return typeof n.traceFlags==`number`&&(n.traceFlags&TraceFlags.SAMPLED)===TraceFlags.SAMPLED}export{batchSpanProcessor};