@@ -333,9 +333,29 @@ func (c *HTTPPoetClient) req(ctx context.Context, method, path string, reqBody,
333
333
}
334
334
335
335
type certifierInfo struct {
336
- obtained time.Time
337
- url * url.URL
338
- pubkey []byte
336
+ url * url.URL
337
+ pubkey []byte
338
+ }
339
+
340
+ type cachedData [T any ] struct {
341
+ mu sync.Mutex
342
+ data T
343
+ exp time.Time
344
+ ttl time.Duration
345
+ }
346
+
347
+ func (c * cachedData [T ]) get (init func () (T , error )) (T , error ) {
348
+ c .mu .Lock ()
349
+ defer c .mu .Unlock ()
350
+ if time .Now ().Before (c .exp ) {
351
+ return c .data , nil
352
+ }
353
+ d , err := init ()
354
+ if err == nil {
355
+ c .data = d
356
+ c .exp = time .Now ().Add (c .ttl )
357
+ }
358
+ return d , err
339
359
}
340
360
341
361
// poetService is a higher-level interface to communicate with a PoET service.
@@ -353,9 +373,8 @@ type poetService struct {
353
373
354
374
certifier certifierService
355
375
356
- certifierInfoTTL time.Duration
357
- certifierInfo certifierInfo
358
- certifierInfoMutex sync.Mutex
376
+ certifierInfoCache cachedData [* certifierInfo ]
377
+ powParamsCache cachedData [* PoetPowParams ]
359
378
}
360
379
361
380
type PoetServiceOpt func (* poetService )
@@ -394,12 +413,13 @@ func NewPoetServiceWithClient(
394
413
opts ... PoetServiceOpt ,
395
414
) * poetService {
396
415
poetClient := & poetService {
397
- db : db ,
398
- logger : logger ,
399
- client : client ,
400
- requestTimeout : cfg .RequestTimeout ,
401
- certifierInfoTTL : cfg .CertifierInfoCacheTTL ,
402
- proofMembers : make (map [string ][]types.Hash32 , 1 ),
416
+ db : db ,
417
+ logger : logger ,
418
+ client : client ,
419
+ requestTimeout : cfg .RequestTimeout ,
420
+ certifierInfoCache : cachedData [* certifierInfo ]{ttl : cfg .CertifierInfoCacheTTL },
421
+ powParamsCache : cachedData [* PoetPowParams ]{ttl : cfg .PowParamsCacheTTL },
422
+ proofMembers : make (map [string ][]types.Hash32 , 1 ),
403
423
}
404
424
405
425
for _ , opt := range opts {
@@ -435,7 +455,7 @@ func (c *poetService) authorize(
435
455
logger .Debug ("querying for poet pow parameters" )
436
456
powCtx , cancel := withConditionalTimeout (ctx , c .requestTimeout )
437
457
defer cancel ()
438
- powParams , err := c .client . PowParams (powCtx )
458
+ powParams , err := c .powParams (powCtx )
439
459
if err != nil {
440
460
return nil , & PoetSvcUnstableError {msg : "failed to get PoW params" , source : err }
441
461
}
@@ -552,19 +572,22 @@ func (c *poetService) recertify(ctx context.Context, id types.NodeID) (*certifie
552
572
}
553
573
554
574
func (c * poetService ) getCertifierInfo (ctx context.Context ) (* url.URL , []byte , error ) {
555
- c .certifierInfoMutex .Lock ()
556
- defer c .certifierInfoMutex .Unlock ()
557
- if time .Since (c .certifierInfo .obtained ) < c .certifierInfoTTL {
558
- return c .certifierInfo .url , c .certifierInfo .pubkey , nil
559
- }
560
- url , pubkey , err := c .client .CertifierInfo (ctx )
575
+ info , err := c .certifierInfoCache .get (func () (* certifierInfo , error ) {
576
+ url , pubkey , err := c .client .CertifierInfo (ctx )
577
+ if err != nil {
578
+ return nil , fmt .Errorf ("getting certifier info: %w" , err )
579
+ }
580
+ return & certifierInfo {url : url , pubkey : pubkey }, nil
581
+ })
561
582
if err != nil {
562
- return nil , nil , fmt .Errorf ("getting certifier info: %w" , err )
563
- }
564
- c .certifierInfo = certifierInfo {
565
- obtained : time .Now (),
566
- url : url ,
567
- pubkey : pubkey ,
583
+ return nil , nil , err
568
584
}
569
- return c .certifierInfo .url , c .certifierInfo .pubkey , nil
585
+
586
+ return info .url , info .pubkey , nil
587
+ }
588
+
589
+ func (c * poetService ) powParams (ctx context.Context ) (* PoetPowParams , error ) {
590
+ return c .powParamsCache .get (func () (* PoetPowParams , error ) {
591
+ return c .client .PowParams (ctx )
592
+ })
570
593
}
0 commit comments