UNPKG

@river-build/sdk

Version:

For more details, visit the following resources:

91 lines 3.82 kB
import { createClient } from '@connectrpc/connect'; import { StreamService } from '@river-build/proto'; import { dlog } from '@river-build/dlog'; import { getEnvVar, randomUrlSelector } from './utils'; import { DEFAULT_RETRY_PARAMS, getRetryDelayMs, loggingInterceptor, retryInterceptor, } from './rpcInterceptors'; import { unpackMiniblock } from './sign'; import { createHttp2ConnectTransport } from './rpcCommon'; import { streamIdAsBytes } from './id'; const logInfo = dlog('csb:rpc:info'); let nextRpcClientNum = 0; export function makeStreamRpcClient(dest, refreshNodeUrl, opts) { const transportId = nextRpcClientNum++; const retryParams = opts?.retryParams ?? DEFAULT_RETRY_PARAMS; logInfo('makeStreamRpcClient, transportId =', transportId); const url = randomUrlSelector(dest); logInfo('makeStreamRpcClient: Connecting to url=', url, ' allUrls=', dest); const options = { baseUrl: url, interceptors: [ ...(opts?.interceptors ?? []), loggingInterceptor(transportId), retryInterceptor({ ...retryParams, refreshNodeUrl }), ], defaultTimeoutMs: undefined, // default timeout is undefined, we add a timeout in the retryInterceptor }; if (getEnvVar('RIVER_DEBUG_TRANSPORT') !== 'true') { options.useBinaryFormat = true; } else { logInfo('makeStreamRpcClient: running in debug mode, using JSON format'); options.useBinaryFormat = false; options.jsonOptions = { alwaysEmitImplicit: true, useProtoFieldName: true, }; } const transport = createHttp2ConnectTransport(options); const client = createClient(StreamService, transport); client.url = url; client.opts = { retryParams }; return client; } export function getMaxTimeoutMs(opts) { let maxTimeoutMs = 0; for (let i = 1; i <= opts.retryParams.maxAttempts; i++) { maxTimeoutMs += opts.retryParams.defaultTimeoutMs ?? 0 + getRetryDelayMs(i, opts.retryParams); } return maxTimeoutMs; } export async function getMiniblocks(client, streamId, fromInclusive, toExclusive, unpackEnvelopeOpts) { const allMiniblocks = []; let currentFromInclusive = fromInclusive; let reachedTerminus = false; while (currentFromInclusive < toExclusive) { const { miniblocks, terminus, nextFromInclusive } = await fetchMiniblocksFromRpc(client, streamId, currentFromInclusive, toExclusive, unpackEnvelopeOpts); allMiniblocks.push(...miniblocks); // Set the terminus to true if we got at least one response with reached terminus // The behaviour around this flag is not implemented yet if (terminus && !reachedTerminus) { reachedTerminus = true; } if (currentFromInclusive === nextFromInclusive) { break; } currentFromInclusive = nextFromInclusive; } return { miniblocks: allMiniblocks, terminus: reachedTerminus, }; } async function fetchMiniblocksFromRpc(client, streamId, fromInclusive, toExclusive, unpackEnvelopeOpts) { const response = await client.getMiniblocks({ streamId: streamIdAsBytes(streamId), fromInclusive, toExclusive, }); const miniblocks = []; for (const miniblock of response.miniblocks) { const unpackedMiniblock = await unpackMiniblock(miniblock, unpackEnvelopeOpts); miniblocks.push(unpackedMiniblock); } const respondedFromInclusive = miniblocks.length > 0 ? miniblocks[0].header.miniblockNum : fromInclusive; return { miniblocks: miniblocks, terminus: response.terminus, nextFromInclusive: respondedFromInclusive + BigInt(response.miniblocks.length), }; } //# sourceMappingURL=makeStreamRpcClient.js.map