1818
1919import static feast .common .models .Store .isSubscribedToFeatureSet ;
2020import static feast .core .model .FeatureSet .parseReference ;
21- import static feast .core .util .StreamUtil .wrapException ;
2221
2322import com .google .common .collect .Sets ;
23+ import com .google .protobuf .InvalidProtocolBufferException ;
2424import feast .common .models .FeatureSetReference ;
2525import feast .core .config .FeastProperties ;
2626import feast .core .config .FeastProperties .JobProperties ;
27- import feast .core .dao .FeatureSetRepository ;
2827import feast .core .job .*;
2928import feast .core .job .task .*;
30- import feast .core .model .*;
31- import feast .core .model .FeatureSet ;
29+ import feast .core .model .FeatureSetDeliveryStatus ;
3230import feast .core .model .Job ;
3331import feast .core .model .JobStatus ;
32+ import feast .proto .core .CoreServiceProto ;
3433import feast .proto .core .CoreServiceProto .ListStoresRequest .Filter ;
3534import feast .proto .core .CoreServiceProto .ListStoresResponse ;
3635import feast .proto .core .FeatureSetProto ;
36+ import feast .proto .core .FeatureSetProto .FeatureSet ;
37+ import feast .proto .core .FeatureSetProto .FeatureSetSpec ;
38+ import feast .proto .core .FeatureSetReferenceProto ;
3739import feast .proto .core .IngestionJobProto ;
3840import feast .proto .core .SourceProto .Source ;
3941import feast .proto .core .StoreProto .Store ;
@@ -59,24 +61,21 @@ public class JobCoordinatorService {
5961 private final int SPEC_PUBLISHING_TIMEOUT_SECONDS = 5 ;
6062
6163 private final JobRepository jobRepository ;
62- private final FeatureSetRepository featureSetRepository ;
6364 private final SpecService specService ;
6465 private final JobManager jobManager ;
6566 private final JobProperties jobProperties ;
6667 private final JobGroupingStrategy groupingStrategy ;
67- private final KafkaTemplate <String , FeatureSetProto . FeatureSetSpec > specPublisher ;
68+ private final KafkaTemplate <String , FeatureSetSpec > specPublisher ;
6869
6970 @ Autowired
7071 public JobCoordinatorService (
7172 JobRepository jobRepository ,
72- FeatureSetRepository featureSetRepository ,
7373 SpecService specService ,
7474 JobManager jobManager ,
7575 FeastProperties feastProperties ,
7676 JobGroupingStrategy groupingStrategy ,
77- KafkaTemplate <String , FeatureSetProto . FeatureSetSpec > specPublisher ) {
77+ KafkaTemplate <String , FeatureSetSpec > specPublisher ) {
7878 this .jobRepository = jobRepository ;
79- this .featureSetRepository = featureSetRepository ;
8079 this .specService = specService ;
8180 this .jobManager = jobManager ;
8281 this .jobProperties = feastProperties .getJobs ();
@@ -236,7 +235,7 @@ private boolean jobRequiresUpgrade(Job job, Set<Store> stores) {
236235 */
237236 FeatureSet allocateFeatureSetToJobs (FeatureSet featureSet ) {
238237 FeatureSetReference ref =
239- FeatureSetReference .of (featureSet .getProject ().getName (), featureSet .getName ());
238+ FeatureSetReference .of (featureSet .getSpec ().getProject (), featureSet . getSpec () .getName ());
240239 Set <String > confirmedJobIds = new HashSet <>();
241240
242241 Stream <Pair <Source , Store >> jobArgsStream =
@@ -245,9 +244,9 @@ FeatureSet allocateFeatureSetToJobs(FeatureSet featureSet) {
245244 s ->
246245 isSubscribedToFeatureSet (
247246 s .getSubscriptionsList (),
248- featureSet .getProject ().getName (),
249- featureSet .getName ()))
250- .map (s -> Pair .of (featureSet .getSource ().toProto (), s ));
247+ featureSet .getSpec ().getProject (),
248+ featureSet .getSpec (). getName ()))
249+ .map (s -> Pair .of (featureSet .getSpec ().getSource (), s ));
251250
252251 // Add featureSet to allocated job if not allocated before
253252 for (Pair <Source , Set <Store >> jobArgs : groupingStrategy .collectSingleJobInput (jobArgsStream )) {
@@ -320,31 +319,47 @@ Iterable<Pair<Source, Set<Store>>> getSourceToStoreMappings() {
320319 * @param store to get subscribed FeatureSets for
321320 * @return list of FeatureSets that the store subscribes to.
322321 */
323- private List <FeatureSetProto . FeatureSet > getFeatureSetsForStore (Store store ) {
322+ private List <FeatureSet > getFeatureSetsForStore (Store store ) {
324323 return store .getSubscriptionsList ().stream ()
325324 .flatMap (
326- subscription ->
327- featureSetRepository
328- .findAllByNameLikeAndProject_NameLikeOrderByNameAsc (
329- subscription .getName ().replace ('*' , '%' ),
330- subscription .getProject ().replace ('*' , '%' ))
331- .stream ())
325+ subscription -> {
326+ try {
327+ return specService
328+ .listFeatureSets (
329+ CoreServiceProto .ListFeatureSetsRequest .Filter .newBuilder ()
330+ .setProject (subscription .getProject ())
331+ .setFeatureSetName (subscription .getName ())
332+ .build ())
333+ .getFeatureSetsList ().stream ();
334+ } catch (InvalidProtocolBufferException e ) {
335+ throw new RuntimeException (
336+ String .format (
337+ "Couldn't fetch featureSets for subscription %s. Reason: %s" ,
338+ subscription , e .getMessage ()));
339+ }
340+ })
332341 .distinct ()
333- .map (wrapException (FeatureSet ::toProto ))
334342 .collect (Collectors .toList ());
335343 }
336344
337345 @ Scheduled (fixedDelayString = "${feast.stream.specsOptions.notifyIntervalMilliseconds}" )
338- public void notifyJobsWhenFeatureSetUpdated () {
346+ public void notifyJobsWhenFeatureSetUpdated () throws InvalidProtocolBufferException {
339347 List <FeatureSet > pendingFeatureSets =
340- featureSetRepository .findAllByStatus (FeatureSetProto .FeatureSetStatus .STATUS_PENDING );
348+ specService
349+ .listFeatureSets (
350+ CoreServiceProto .ListFeatureSetsRequest .Filter .newBuilder ()
351+ .setProject ("*" )
352+ .setFeatureSetName ("*" )
353+ .setStatus (FeatureSetProto .FeatureSetStatus .STATUS_PENDING )
354+ .build ())
355+ .getFeatureSetsList ();
341356
342357 pendingFeatureSets .stream ()
343358 .map (this ::allocateFeatureSetToJobs )
344359 .map (
345360 fs -> {
346361 FeatureSetReference ref =
347- FeatureSetReference .of (fs .getProject ().getName (), fs .getName ());
362+ FeatureSetReference .of (fs .getSpec ().getProject (), fs . getSpec () .getName ());
348363 List <FeatureSetDeliveryStatus > deliveryStatuses =
349364 jobRepository .findByFeatureSetReference (ref ).stream ()
350365 .filter (Job ::isRunning )
@@ -360,13 +375,17 @@ public void notifyJobsWhenFeatureSetUpdated() {
360375 && pair .getRight ().stream ()
361376 .anyMatch (
362377 jobStatus ->
363- jobStatus .getDeliveredVersion () < pair .getLeft ().getVersion ()))
378+ jobStatus .getDeliveredVersion ()
379+ < pair .getLeft ().getSpec ().getVersion ()))
364380 .forEach (
365381 pair -> {
366382 FeatureSet fs = pair .getLeft ();
367383 List <FeatureSetDeliveryStatus > deliveryStatuses = pair .getRight ();
368384
369- log .info ("Sending new FeatureSet {} to Ingestion" , fs .getReference ());
385+ FeatureSetReference ref =
386+ FeatureSetReference .of (fs .getSpec ().getProject (), fs .getSpec ().getName ());
387+
388+ log .info ("Sending new FeatureSet {} to Ingestion" , ref );
370389
371390 // Sending latest version of FeatureSet to all currently running IngestionJobs
372391 // (there's one topic for all sets).
@@ -375,7 +394,7 @@ public void notifyJobsWhenFeatureSetUpdated() {
375394 // again later.
376395 try {
377396 specPublisher
378- .sendDefault (fs .getReference (), fs . toProto () .getSpec ())
397+ .sendDefault (ref .getReference (), fs .getSpec ())
379398 .get (SPEC_PUBLISHING_TIMEOUT_SECONDS , TimeUnit .SECONDS );
380399 } catch (Exception e ) {
381400 log .error (
@@ -393,7 +412,7 @@ public void notifyJobsWhenFeatureSetUpdated() {
393412 jobStatus -> {
394413 jobStatus .setDeliveryStatus (
395414 FeatureSetProto .FeatureSetJobDeliveryStatus .STATUS_IN_PROGRESS );
396- jobStatus .setDeliveredVersion (fs .getVersion ());
415+ jobStatus .setDeliveredVersion (fs .getSpec (). getVersion ());
397416 });
398417 });
399418 }
@@ -412,13 +431,19 @@ public void notifyJobsWhenFeatureSetUpdated() {
412431 @ KafkaListener (
413432 topics = {"${feast.stream.specsOptions.specsAckTopic}" },
414433 containerFactory = "kafkaAckListenerContainerFactory" )
415- public void listenAckFromJobs (
416- ConsumerRecord < String , IngestionJobProto . FeatureSetSpecAck > record ) {
434+ public void listenAckFromJobs (ConsumerRecord < String , IngestionJobProto . FeatureSetSpecAck > record )
435+ throws InvalidProtocolBufferException {
417436 String setReference = record .key ();
418437 Pair <String , String > projectAndSetName = parseReference (setReference );
419438 FeatureSet featureSet =
420- featureSetRepository .findFeatureSetByNameAndProject_Name (
421- projectAndSetName .getRight (), projectAndSetName .getLeft ());
439+ specService
440+ .getFeatureSet (
441+ CoreServiceProto .GetFeatureSetRequest .newBuilder ()
442+ .setProject (projectAndSetName .getLeft ())
443+ .setName (projectAndSetName .getRight ())
444+ .build ())
445+ .getFeatureSet ();
446+
422447 if (featureSet == null ) {
423448 log .warn (
424449 String .format ("ACKListener received message for unknown FeatureSet %s" , setReference ));
@@ -427,18 +452,18 @@ public void listenAckFromJobs(
427452
428453 int ackVersion = record .value ().getFeatureSetVersion ();
429454
430- if (featureSet .getVersion () != ackVersion ) {
455+ if (featureSet .getSpec (). getVersion () != ackVersion ) {
431456 log .warn (
432457 String .format (
433458 "ACKListener received outdated ack for %s. Current %d, Received %d" ,
434- setReference , featureSet .getVersion (), ackVersion ));
459+ setReference , featureSet .getSpec (). getVersion (), ackVersion ));
435460 return ;
436461 }
437462
438- log .info ("Updating featureSet {} delivery statuses." , featureSet .getReference ());
439-
440463 FeatureSetReference ref =
441- FeatureSetReference .of (featureSet .getProject ().getName (), featureSet .getName ());
464+ FeatureSetReference .of (featureSet .getSpec ().getProject (), featureSet .getSpec ().getName ());
465+
466+ log .info ("Updating featureSet {} delivery statuses." , ref );
442467
443468 jobRepository
444469 .findById (record .value ().getJobName ())
@@ -459,10 +484,17 @@ public void listenAckFromJobs(
459484 .equals (FeatureSetProto .FeatureSetJobDeliveryStatus .STATUS_DELIVERED ));
460485
461486 if (allDelivered ) {
462- log .info ("FeatureSet {} update is completely delivered" , featureSet .getReference ());
463-
464- featureSet .setStatus (FeatureSetProto .FeatureSetStatus .STATUS_READY );
465- featureSetRepository .saveAndFlush (featureSet );
487+ log .info ("FeatureSet {} update is completely delivered" , ref );
488+
489+ specService .updateFeatureSetStatus (
490+ CoreServiceProto .UpdateFeatureSetStatusRequest .newBuilder ()
491+ .setReference (
492+ FeatureSetReferenceProto .FeatureSetReference .newBuilder ()
493+ .setName (ref .getFeatureSetName ())
494+ .setProject (ref .getProjectName ())
495+ .build ())
496+ .setStatus (FeatureSetProto .FeatureSetStatus .STATUS_READY )
497+ .build ());
466498 }
467499 }
468500}
0 commit comments