Portal Community

appendLog Implementation

// executionStore.ts
appendLog: (entry: LogEntry) => set(state => {
    // Idempotency check — skip if logId already in array
    if (state.logs.some(l => l.logId === entry.logId)) {
        return state;  // Return unchanged state — no re-render triggered
    }

    return {
        logs: [...state.logs, entry]
    };
}),

// Batch append (called for historical loads and large SignalR batches)
appendLogs: (entries: LogEntry[]) => set(state => {
    const existingIds = new Set(state.logs.map(l => l.logId));
    const newEntries  = entries.filter(e => !existingIds.has(e.logId));

    if (newEntries.length === 0) return state;  // No change

    return {
        logs: [...state.logs, ...newEntries]
    };
})

SignalR Handler

// useExecutionSignalR.ts — called on every NodeLogEmitted event
connection.on('NodeLogEmitted', (payload: { entries: LogEntry[] }) => {
    useExecutionStore.getState().appendLogs(payload.entries);
    // Batch append — more efficient than calling appendLog N times
});

Why Idempotency Matters

Three scenarios can cause the same log entry to arrive twice on the client:

ScenarioHow Duplicate Occurs
SignalR reconnectClient reconnects mid-execution and replays missed events — some may already be in the array
Historical load after live viewHistorical API returns all logs — some were already streamed live
Multiple observer tabsIf two tabs are open for the same execution, each receives events — mergeable if shared store
logId is a server-assigned GUID. It is generated in SignalRLogSink before the entry enters the buffer. The client never generates or modifies logIds — it only reads them for deduplication.