@@ -90,13 +90,25 @@ func (a *cascadeAdapter) CascadeSupernodeRegister(ctx context.Context, in *Casca
9090 if err != nil {
9191 a .logger .Error (ctx , "Failed to create register stream" ,
9292 "error" , err )
93+ if in .EventLogger != nil {
94+ in .EventLogger (baseCtx , event .SDKUploadFailed , "upload failed | reason=stream_open" , event.EventData {
95+ event .KeyTaskID : in .TaskId ,
96+ event .KeyActionID : in .ActionID ,
97+ })
98+ }
9399 return nil , err
94100 }
95101
96102 // Open the file for reading
97103 file , err := os .Open (in .FilePath )
98104 if err != nil {
99105 a .logger .Error (ctx , "Failed to open file" , "filePath" , in .FilePath , "error" , err )
106+ if in .EventLogger != nil {
107+ in .EventLogger (baseCtx , event .SDKUploadFailed , "upload failed | reason=file_open" , event.EventData {
108+ event .KeyTaskID : in .TaskId ,
109+ event .KeyActionID : in .ActionID ,
110+ })
111+ }
100112 return nil , fmt .Errorf ("failed to open file: %w" , err )
101113 }
102114 defer file .Close ()
@@ -105,6 +117,12 @@ func (a *cascadeAdapter) CascadeSupernodeRegister(ctx context.Context, in *Casca
105117 fileInfo , err := file .Stat ()
106118 if err != nil {
107119 a .logger .Error (ctx , "Failed to get file stats" , "filePath" , in .FilePath , "error" , err )
120+ if in .EventLogger != nil {
121+ in .EventLogger (baseCtx , event .SDKUploadFailed , "upload failed | reason=file_stat" , event.EventData {
122+ event .KeyTaskID : in .TaskId ,
123+ event .KeyActionID : in .ActionID ,
124+ })
125+ }
108126 return nil , fmt .Errorf ("failed to get file stats: %w" , err )
109127 }
110128 totalBytes := fileInfo .Size ()
@@ -128,14 +146,21 @@ func (a *cascadeAdapter) CascadeSupernodeRegister(ctx context.Context, in *Casca
128146 chunkIndex := 0
129147 buffer := make ([]byte , chunkSize )
130148
149+ // Emit upload started event
150+ if in .EventLogger != nil {
151+ estChunks := (totalBytes + int64 (chunkSize ) - 1 ) / int64 (chunkSize )
152+ in .EventLogger (baseCtx , event .SDKUploadStarted ,
153+ fmt .Sprintf ("upload started | size=%dB chunk_size=%dB est_chunks=%d" , totalBytes , chunkSize , estChunks ),
154+ event.EventData {event .KeyTaskID : in .TaskId , event .KeyActionID : in .ActionID })
155+ }
156+
157+ uploadStart := time .Now ()
158+
131159 // Start upload phase timer
132160 uploadTimer := time .AfterFunc (cascadeUploadTimeout , func () {
133161 a .logger .Error (baseCtx , "Upload phase timeout reached; cancelling stream" )
134162 if in .EventLogger != nil {
135- in .EventLogger (baseCtx , event .SDKUploadTimeout , "upload phase timeout" , event.EventData {
136- event .KeyTaskID : in .TaskId ,
137- event .KeyActionID : in .ActionID ,
138- })
163+ in .EventLogger (baseCtx , event .SDKUploadFailed , "upload failed | reason=timeout" , event.EventData {event .KeyTaskID : in .TaskId , event .KeyActionID : in .ActionID })
139164 }
140165 cancel ()
141166 })
@@ -149,6 +174,12 @@ func (a *cascadeAdapter) CascadeSupernodeRegister(ctx context.Context, in *Casca
149174 }
150175 if err != nil {
151176 a .logger .Error (ctx , "Failed to read file chunk" , "chunkIndex" , chunkIndex , "error" , err )
177+ if in .EventLogger != nil {
178+ in .EventLogger (baseCtx , event .SDKUploadFailed , fmt .Sprintf ("upload failed | reason=read_error chunk=%d" , chunkIndex ), event.EventData {
179+ event .KeyTaskID : in .TaskId ,
180+ event .KeyActionID : in .ActionID ,
181+ })
182+ }
152183 return nil , fmt .Errorf ("failed to read file chunk: %w" , err )
153184 }
154185
@@ -163,6 +194,12 @@ func (a *cascadeAdapter) CascadeSupernodeRegister(ctx context.Context, in *Casca
163194
164195 if err := stream .Send (chunk ); err != nil {
165196 a .logger .Error (ctx , "Failed to send data chunk" , "chunkIndex" , chunkIndex , "error" , err )
197+ if in .EventLogger != nil {
198+ in .EventLogger (baseCtx , event .SDKUploadFailed , fmt .Sprintf ("upload failed | reason=send_error chunk=%d" , chunkIndex ), event.EventData {
199+ event .KeyTaskID : in .TaskId ,
200+ event .KeyActionID : in .ActionID ,
201+ })
202+ }
166203 return nil , fmt .Errorf ("failed to send chunk: %w" , err )
167204 }
168205
@@ -186,13 +223,25 @@ func (a *cascadeAdapter) CascadeSupernodeRegister(ctx context.Context, in *Casca
186223
187224 if err := stream .Send (metadata ); err != nil {
188225 a .logger .Error (ctx , "Failed to send metadata" , "TaskId" , in .TaskId , "ActionID" , in .ActionID , "error" , err )
226+ if in .EventLogger != nil {
227+ in .EventLogger (baseCtx , event .SDKUploadFailed , "upload failed | reason=send_metadata" , event.EventData {
228+ event .KeyTaskID : in .TaskId ,
229+ event .KeyActionID : in .ActionID ,
230+ })
231+ }
189232 return nil , fmt .Errorf ("failed to send metadata: %w" , err )
190233 }
191234
192235 a .logger .Debug (ctx , "Sent metadata" , "TaskId" , in .TaskId , "ActionID" , in .ActionID )
193236
194237 if err := stream .CloseSend (); err != nil {
195238 a .logger .Error (ctx , "Failed to close stream and receive response" , "TaskId" , in .TaskId , "ActionID" , in .ActionID , "error" , err )
239+ if in .EventLogger != nil {
240+ in .EventLogger (baseCtx , event .SDKUploadFailed , "upload failed | reason=close_send" , event.EventData {
241+ event .KeyTaskID : in .TaskId ,
242+ event .KeyActionID : in .ActionID ,
243+ })
244+ }
196245 return nil , fmt .Errorf ("failed to receive response: %w" , err )
197246 }
198247
@@ -201,14 +250,24 @@ func (a *cascadeAdapter) CascadeSupernodeRegister(ctx context.Context, in *Casca
201250 uploadTimer .Stop ()
202251 }
203252
253+ // Emit upload completed with throughput metrics
254+ if in .EventLogger != nil {
255+ elapsed := time .Since (uploadStart ).Seconds ()
256+ mb := float64 (bytesRead ) / (1024.0 * 1024.0 )
257+ avg := 0.0
258+ if elapsed > 0 {
259+ avg = mb / elapsed
260+ }
261+ in .EventLogger (baseCtx , event .SDKUploadCompleted ,
262+ fmt .Sprintf ("upload complete | size=%dB chunks=%d elapsed=%.2fs avg=%.2fMB/s" , totalBytes , chunkIndex , elapsed , avg ),
263+ event.EventData {event .KeyTaskID : in .TaskId , event .KeyActionID : in .ActionID })
264+ }
265+
204266 // Processing phase timer starts now (waiting for server streamed responses)
205267 processingTimer := time .AfterFunc (cascadeProcessingTimeout , func () {
206268 a .logger .Error (baseCtx , "Processing phase timeout reached; cancelling stream" )
207269 if in .EventLogger != nil {
208- in .EventLogger (baseCtx , event .SDKProcessingTimeout , "processing phase timeout" , event.EventData {
209- event .KeyTaskID : in .TaskId ,
210- event .KeyActionID : in .ActionID ,
211- })
270+ in .EventLogger (baseCtx , event .SDKProcessingTimeout , "processing timeout" , event.EventData {event .KeyTaskID : in .TaskId , event .KeyActionID : in .ActionID })
212271 }
213272 cancel ()
214273 })
@@ -218,6 +277,11 @@ func (a *cascadeAdapter) CascadeSupernodeRegister(ctx context.Context, in *Casca
218277 }
219278 }()
220279
280+ // Emit processing started
281+ if in .EventLogger != nil {
282+ in .EventLogger (baseCtx , event .SDKProcessingStarted , "processing started | awaiting server progress" , event.EventData {event .KeyTaskID : in .TaskId , event .KeyActionID : in .ActionID })
283+ }
284+
221285 // Handle streaming responses from supernode
222286 var finalResp * cascade.RegisterResponse
223287 for {
@@ -228,12 +292,16 @@ func (a *cascadeAdapter) CascadeSupernodeRegister(ctx context.Context, in *Casca
228292 if err != nil {
229293 // Distinguish timeout phase for clearer error messages
230294 if phaseCtx .Err () != nil {
231- // Determine which phase we were in by whether upload finished
232295 // At this point, upload is finished; classify as processing timeout/cancel
233296 if phaseCtx .Err () == context .DeadlineExceeded || phaseCtx .Err () == context .Canceled {
234297 return nil , fmt .Errorf ("processing timed out or cancelled: %w" , phaseCtx .Err ())
235298 }
236299 }
300+ if in .EventLogger != nil {
301+ in .EventLogger (baseCtx , event .SDKProcessingFailed ,
302+ fmt .Sprintf ("processing failed | reason=stream_recv error=%v" , err ),
303+ event.EventData {event .KeyTaskID : in .TaskId , event .KeyActionID : in .ActionID })
304+ }
237305 return nil , fmt .Errorf ("failed to receive server response: %w" , err )
238306 }
239307
@@ -268,6 +336,9 @@ func (a *cascadeAdapter) CascadeSupernodeRegister(ctx context.Context, in *Casca
268336 if phaseCtx .Err () != nil {
269337 return nil , fmt .Errorf ("processing timed out or cancelled before final response: %w" , phaseCtx .Err ())
270338 }
339+ if in .EventLogger != nil {
340+ in .EventLogger (baseCtx , event .SDKProcessingFailed , "processing failed | reason=missing_final_response" , event.EventData {event .KeyTaskID : in .TaskId , event .KeyActionID : in .ActionID })
341+ }
271342 return nil , fmt .Errorf ("no final response with tx_hash received" )
272343 }
273344
@@ -380,7 +451,7 @@ func (a *cascadeAdapter) CascadeSupernodeDownload(
380451
381452// toSdkEvent converts a supernode-side enum value into an internal SDK EventType.
382453func toSdkEvent (e cascade.SupernodeEventType ) event.EventType {
383- switch e {
454+ switch e {
384455 case cascade .SupernodeEventType_ACTION_RETRIEVED :
385456 return event .SupernodeActionRetrieved
386457 case cascade .SupernodeEventType_ACTION_FEE_VERIFIED :
@@ -405,8 +476,10 @@ func toSdkEvent(e cascade.SupernodeEventType) event.EventType {
405476 return event .SupernodeActionFinalized
406477 case cascade .SupernodeEventType_ARTEFACTS_DOWNLOADED :
407478 return event .SupernodeArtefactsDownloaded
408- case cascade .SupernodeEventType_FINALIZE_SIMULATED :
409- return event .SupernodeFinalizeSimulated
479+ case cascade .SupernodeEventType_FINALIZE_SIMULATED :
480+ return event .SupernodeFinalizeSimulated
481+ case cascade .SupernodeEventType_FINALIZE_SIMULATION_FAILED :
482+ return event .SupernodeFinalizeSimulationFailed
410483 default :
411484 return event .SupernodeUnknown
412485 }
0 commit comments