1
+ use std:: time:: Instant ;
2
+
1
3
use async_trait:: async_trait;
2
4
use dkn_p2p:: libp2p:: gossipsub:: MessageAcceptance ;
3
5
use dkn_workflows:: { Entry , Executor , ModelProvider , ProgramMemory , Workflow } ;
4
6
use eyre:: { eyre, Context , Result } ;
5
7
use libsecp256k1:: PublicKey ;
6
8
use serde:: Deserialize ;
7
9
8
- use crate :: payloads:: { TaskErrorPayload , TaskRequestPayload , TaskResponsePayload } ;
10
+ use crate :: payloads:: { TaskErrorPayload , TaskRequestPayload , TaskResponsePayload , TaskStats } ;
9
11
use crate :: utils:: { get_current_time_nanos, DKNMessage } ;
10
12
use crate :: DriaComputeNode ;
11
13
@@ -38,6 +40,7 @@ impl ComputeHandler for WorkflowHandler {
38
40
let task = message
39
41
. parse_payload :: < TaskRequestPayload < WorkflowPayload > > ( true )
40
42
. wrap_err ( "Could not parse workflow task" ) ?;
43
+ let mut task_stats = TaskStats :: default ( ) . record_received_at ( ) ;
41
44
42
45
// check if deadline is past or not
43
46
let current_time = get_current_time_nanos ( ) ;
@@ -90,6 +93,7 @@ impl ComputeHandler for WorkflowHandler {
90
93
91
94
// execute workflow with cancellation
92
95
let exec_result: Result < String > ;
96
+ let exec_started_at = Instant :: now ( ) ;
93
97
tokio:: select! {
94
98
_ = node. cancellation. cancelled( ) => {
95
99
log:: info!( "Received cancellation, quitting all tasks." ) ;
@@ -99,10 +103,10 @@ impl ComputeHandler for WorkflowHandler {
99
103
exec_result = exec_result_inner. map_err( |e| eyre!( "Execution error: {}" , e. to_string( ) ) ) ;
100
104
}
101
105
}
106
+ task_stats = task_stats. record_execution_time ( exec_started_at) ;
102
107
103
- let ( publish_result , acceptance) = match exec_result {
108
+ let ( message , acceptance) = match exec_result {
104
109
Ok ( result) => {
105
- log:: warn!( "Task {} result:" , result) ;
106
110
// obtain public key from the payload
107
111
let task_public_key_bytes =
108
112
hex:: decode ( & task. public_key ) . wrap_err ( "Could not decode public key" ) ?;
@@ -115,44 +119,56 @@ impl ComputeHandler for WorkflowHandler {
115
119
& task_public_key,
116
120
& node. config . secret_key ,
117
121
model_name,
122
+ task_stats. record_published_at ( ) ,
118
123
) ?;
119
124
let payload_str = serde_json:: to_string ( & payload)
120
125
. wrap_err ( "Could not serialize response payload" ) ?;
121
126
122
- // publish the result
123
- // accept so that if there are others included in filter they can do the task
127
+ // prepare signed message
128
+ log:: debug!(
129
+ "Publishing result for task {}\n {}" ,
130
+ task. task_id,
131
+ payload_str
132
+ ) ;
124
133
let message = DKNMessage :: new ( payload_str, Self :: RESPONSE_TOPIC ) ;
125
- ( node. publish ( message) , MessageAcceptance :: Accept )
134
+ // accept so that if there are others included in filter they can do the task
135
+ ( message, MessageAcceptance :: Accept )
126
136
}
127
137
Err ( err) => {
128
138
// use pretty display string for error logging with causes
129
139
let err_string = format ! ( "{:#}" , err) ;
130
140
log:: error!( "Task {} failed: {}" , task. task_id, err_string) ;
131
141
132
142
// prepare error payload
133
- let error_payload =
134
- TaskErrorPayload :: new ( task. task_id . clone ( ) , err_string, model_name) ;
143
+ let error_payload = TaskErrorPayload {
144
+ task_id : task. task_id . clone ( ) ,
145
+ error : err_string,
146
+ model : model_name,
147
+ stats : task_stats. record_published_at ( ) ,
148
+ } ;
135
149
let error_payload_str = serde_json:: to_string ( & error_payload)
136
150
. wrap_err ( "Could not serialize error payload" ) ?;
137
151
138
- // publish the error result for diagnostics
139
- // ignore just in case, workflow may be bugged
152
+ // prepare signed message
140
153
let message = DKNMessage :: new_signed (
141
154
error_payload_str,
142
155
Self :: RESPONSE_TOPIC ,
143
156
& node. config . secret_key ,
144
157
) ;
145
- ( node. publish ( message) , MessageAcceptance :: Ignore )
158
+ // ignore just in case, workflow may be bugged
159
+ ( message, MessageAcceptance :: Ignore )
146
160
}
147
161
} ;
148
162
149
- // if for some reason we couldnt publish the result, publish the error itself so that RPC doesnt hang
150
- if let Err ( publish_err) = publish_result {
163
+ // try publishing the result
164
+
165
+ if let Err ( publish_err) = node. publish ( message) {
151
166
let err_msg = format ! ( "Could not publish result: {:?}" , publish_err) ;
152
167
log:: error!( "{}" , err_msg) ;
168
+
153
169
let payload = serde_json:: json!( {
154
170
"taskId" : task. task_id,
155
- "error" : err_msg
171
+ "error" : err_msg,
156
172
} ) ;
157
173
let message = DKNMessage :: new_signed (
158
174
payload. to_string ( ) ,
0 commit comments