@@ -241,17 +241,21 @@ func (e *ETCD) BatchUpdate(ctx context.Context, data map[string]string, opts ...
241
241
242
242
// BindStatus keeps on a lease alive.
243
243
func (e * ETCD ) BindStatus (ctx context.Context , entityKey , statusKey , statusValue string , ttl int64 ) error {
244
- var leaseID clientv3.LeaseID
245
- updateStatus := []clientv3.Op {clientv3 .OpPut (statusKey , statusValue )}
246
- if ttl != 0 {
247
- lease , err := e .Grant (ctx , ttl )
248
- if err != nil {
249
- return err
250
- }
251
- leaseID = lease .ID
252
- updateStatus = []clientv3.Op {clientv3 .OpPut (statusKey , statusValue , clientv3 .WithLease (lease .ID ))}
244
+ if ttl == 0 {
245
+ return e .bindStatusWithoutTTL (ctx , statusKey , statusValue )
246
+ }
247
+ return e .bindStatusWithTTL (ctx , entityKey , statusKey , statusValue , ttl )
248
+ }
249
+
250
+ func (e * ETCD ) bindStatusWithTTL (ctx context.Context , entityKey , statusKey , statusValue string , ttl int64 ) error {
251
+ lease , err := e .Grant (ctx , ttl )
252
+ if err != nil {
253
+ return err
253
254
}
254
255
256
+ leaseID := lease .ID
257
+ updateStatus := []clientv3.Op {clientv3 .OpPut (statusKey , statusValue , clientv3 .WithLease (lease .ID ))}
258
+
255
259
entityTxn , err := e .cliv3 .Txn (ctx ).
256
260
If (clientv3 .Compare (clientv3 .Version (entityKey ), "!=" , 0 )).
257
261
Then ( // making sure there's an exists entity kv-pair.
@@ -282,11 +286,6 @@ func (e *ETCD) BindStatus(ctx context.Context, entityKey, statusKey, statusValue
282
286
return nil
283
287
}
284
288
285
- // A zero TTL means it doesn't affect anything
286
- if ttl == 0 {
287
- return nil
288
- }
289
-
290
289
// There is a status bound to the entity yet but its value isn't same as the expected one.
291
290
valueTxn := statusTxn .Responses [0 ].GetResponseTxn ()
292
291
if ! valueTxn .Succeeded {
@@ -304,6 +303,24 @@ func (e *ETCD) BindStatus(ctx context.Context, entityKey, statusKey, statusValue
304
303
return err
305
304
}
306
305
306
+ // bindStatusWithoutTTL sets status without TTL.
307
+ // When dealing with status of 0 TTL, we don't use lease,
308
+ // also we don't check the existence of the entity key since
309
+ // agent may report status earlier when core has not recorded the entity.
310
+ func (e * ETCD ) bindStatusWithoutTTL (ctx context.Context , statusKey , statusValue string ) error {
311
+ updateStatus := []clientv3.Op {clientv3 .OpPut (statusKey , statusValue )}
312
+ _ , err := e .cliv3 .Txn (ctx ).
313
+ If (clientv3 .Compare (clientv3 .Version (statusKey ), "!=" , 0 )). // if there's an existing status key
314
+ Then (clientv3 .OpTxn ( // deal with existing status key
315
+ []clientv3.Cmp {clientv3 .Compare (clientv3 .Value (statusKey ), "!=" , statusValue )}, // if the new value != the old value
316
+ updateStatus , // then the status has been changed.
317
+ []clientv3.Op {}, // otherwise do nothing.
318
+ )).
319
+ Else (updateStatus ... ). // otherwise deal with non-existing status key
320
+ Commit ()
321
+ return err
322
+ }
323
+
307
324
func (e * ETCD ) revokeLease (ctx context.Context , leaseID clientv3.LeaseID ) {
308
325
if leaseID == 0 {
309
326
return
0 commit comments