Skip to content

Commit 149065c

Browse files
author
Aalyria Technologies, Inc
committed
Import changes.
- 034898d4f08fb9f962a64ec369ba0008dba929b2 GitOrigin-RevId: 034898d4f08fb9f962a64ec369ba0008dba929b2
1 parent e292e5e commit 149065c

3 files changed

Lines changed: 213 additions & 142 deletions

File tree

tools/nbictl/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ go_library(
5555
"@com_github_jhump_protoreflect//grpcreflect",
5656
"@com_github_jonboulle_clockwork//:clockwork",
5757
"@com_github_samber_lo//:lo",
58+
"@com_github_sourcegraph_conc//pool",
5859
"@com_github_urfave_cli_v2//:cli",
5960
"@org_golang_google_genproto//googleapis/type/interval",
6061
"@org_golang_google_grpc//:grpc",

tools/nbictl/model.go

Lines changed: 119 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222

2323
modelpb "aalyria.com/spacetime/api/model/v1"
2424
set "github.com/deckarep/golang-set/v2"
25-
"github.com/samber/lo"
25+
"github.com/sourcegraph/conc/pool"
2626
"github.com/urfave/cli/v2"
2727
"google.golang.org/grpc/codes"
2828
"google.golang.org/grpc/status"
@@ -325,6 +325,11 @@ func ModelListRelationships(appCtx *cli.Context) error {
325325

326326
func nmtsEntitiesAreEquivalent(a, b *nmtspb.Entity) bool {
327327
// TODO: find a more robust equivalency check.
328+
// Additionally, allow for not overwriting certain changes,
329+
// like not changing interface admin status (because this
330+
// can be changed in the UI), and perhaps not changing
331+
// a KeplerianElements if the only change is the epoch
332+
// time (just wastes a lot of motion computation).
328333
return proto.Equal(a, b)
329334
}
330335

@@ -405,22 +410,34 @@ func ModelSync(appCtx *cli.Context) error {
405410
defer conn.Close()
406411
modelClient := modelpb.NewModelClient(conn)
407412

408-
entityList, err := modelClient.ListEntities(appCtx.Context, &modelpb.ListEntitiesRequest{})
409-
if err != nil {
410-
return err
411-
}
412-
for _, entity := range entityList.GetEntities() {
413-
remoteEntities[entity.GetId()] = entity
414-
}
415-
remoteEntityKeys := set.NewSetFromMapKeys(remoteEntities)
413+
listPool := pool.New().WithErrors()
416414

417-
relationshipList, err := modelClient.ListRelationships(appCtx.Context, &modelpb.ListRelationshipsRequest{})
418-
if err != nil {
415+
listPool.Go(func() error {
416+
entityList, err := modelClient.ListEntities(appCtx.Context, &modelpb.ListEntitiesRequest{})
417+
if err != nil {
418+
return err
419+
}
420+
for _, entity := range entityList.GetEntities() {
421+
remoteEntities[entity.GetId()] = entity
422+
}
423+
return nil
424+
})
425+
426+
listPool.Go(func() error {
427+
relationshipList, err := modelClient.ListRelationships(appCtx.Context, &modelpb.ListRelationshipsRequest{})
428+
if err != nil {
429+
return err
430+
}
431+
for _, relationship := range relationshipList.GetRelationships() {
432+
remoteRelationships.Insert(er.RelationshipFromProto(relationship))
433+
}
434+
return nil
435+
})
436+
437+
if err = listPool.Wait(); err != nil {
419438
return err
420439
}
421-
for _, relationship := range relationshipList.GetRelationships() {
422-
remoteRelationships.Insert(er.RelationshipFromProto(relationship))
423-
}
440+
remoteEntityKeys := set.NewSetFromMapKeys(remoteEntities)
424441
remoteRelationshipKeys := set.NewSetFromMapKeys(remoteRelationships.Relations)
425442
fmt.Fprintf(os.Stdout, "remote model elements:\n")
426443
fmt.Fprintf(os.Stdout, "- %d NMTS Entities\n", remoteEntityKeys.Cardinality())
@@ -434,96 +451,119 @@ func ModelSync(appCtx *cli.Context) error {
434451

435452
errs := []error{}
436453

454+
// Update entities.
455+
updatePool := pool.New().WithErrors()
456+
entitiesInCommon := localEntityKeys.Intersect(remoteEntityKeys)
457+
for entity := range entitiesInCommon.Iter() {
458+
updatePool.Go(func() error {
459+
if nmtsEntitiesAreEquivalent(localEntities[entity], remoteEntities[entity]) {
460+
return nil
461+
}
462+
if printMode {
463+
fmt.Printf("update entity: %s\n", entity)
464+
}
465+
var err error
466+
if !dryRunMode {
467+
_, err = modelClient.UpdateEntity(appCtx.Context, &modelpb.UpdateEntityRequest{
468+
Entity: localEntities[entity],
469+
})
470+
}
471+
return err
472+
})
473+
}
474+
437475
// Maybe delete entities (and prune collaterally deleted relationships)
438-
// Maybe delete relationships.
476+
deleteEntitiesPool := pool.New().WithErrors()
439477
if deleteMode {
440478
entitiesToBeDeleted := remoteEntityKeys.Difference(localEntityKeys)
441-
relationshipsToBeDeleted := remoteRelationshipKeys.Difference(localRelationshipKeys)
442479

443480
for entity := range entitiesToBeDeleted.Iter() {
444-
if printMode {
445-
fmt.Printf("delete entity: %s\n", entity)
446-
}
447-
if !dryRunMode {
448-
deleteResponse, err := modelClient.DeleteEntity(appCtx.Context, &modelpb.DeleteEntityRequest{
449-
EntityId: entity,
450-
})
451-
if err != nil && !isNotFoundError(err) {
452-
errs = append(errs, err)
453-
} else {
454-
relationshipsToBeDeleted.RemoveAll(
455-
lo.Map(deleteResponse.GetDeletedRelationships(), func(r *nmtspb.Relationship, _ int) er.Relationship {
456-
return er.RelationshipFromProto(r)
457-
})...)
481+
deleteEntitiesPool.Go(func() error {
482+
if printMode {
483+
fmt.Printf("delete entity: %s\n", entity)
458484
}
459-
}
485+
var err error
486+
if !dryRunMode {
487+
_, err = modelClient.DeleteEntity(appCtx.Context, &modelpb.DeleteEntityRequest{
488+
EntityId: entity,
489+
})
490+
if err != nil && isNotFoundError(err) {
491+
err = nil
492+
}
493+
// TODO: retrieve list of deleted relationships
494+
// from DeleteEntityResponse and prune them from
495+
// the relationshipsToBeDeleted set.
496+
}
497+
return err
498+
})
460499
}
500+
}
501+
502+
errs = append(errs, updatePool.Wait())
503+
errs = append(errs, deleteEntitiesPool.Wait())
461504

505+
// Maybe delete relationships.
506+
deleteRelationshipsPool := pool.New().WithErrors()
507+
if deleteMode {
508+
relationshipsToBeDeleted := remoteRelationshipKeys.Difference(localRelationshipKeys)
462509
for relationship := range relationshipsToBeDeleted.Iter() {
463-
if printMode {
464-
fmt.Printf("delete relationship: %s\n", relationship)
465-
}
466-
if !dryRunMode {
467-
_, err := modelClient.DeleteRelationship(appCtx.Context, &modelpb.DeleteRelationshipRequest{
468-
Relationship: relationship.ToProto(),
469-
})
470-
if err != nil {
471-
errs = append(errs, err)
510+
deleteRelationshipsPool.Go(func() error {
511+
if printMode {
512+
fmt.Printf("delete relationship: %s\n", relationship)
472513
}
473-
}
514+
var err error
515+
if !dryRunMode {
516+
_, err = modelClient.DeleteRelationship(appCtx.Context, &modelpb.DeleteRelationshipRequest{
517+
Relationship: relationship.ToProto(),
518+
})
519+
}
520+
return err
521+
})
474522
}
475523
}
524+
// Wait for relationship deletes before adding entities and
525+
// relationships that might create difficult-to-analyze graphs.
526+
errs = append(errs, deleteRelationshipsPool.Wait())
476527

477528
// Add entities.
529+
addEntitiesPool := pool.New().WithErrors()
478530
entitiesToBeAdded := localEntityKeys.Difference(remoteEntityKeys)
479531
for entity := range entitiesToBeAdded.Iter() {
480-
if printMode {
481-
fmt.Printf("add entity: %s\n", entity)
482-
}
483-
if !dryRunMode {
484-
_, err := modelClient.CreateEntity(appCtx.Context, &modelpb.CreateEntityRequest{
485-
Entity: localEntities[entity],
486-
})
487-
if err != nil {
488-
errs = append(errs, err)
532+
addEntitiesPool.Go(func() error {
533+
if printMode {
534+
fmt.Printf("add entity: %s\n", entity)
489535
}
490-
}
536+
var err error
537+
if !dryRunMode {
538+
_, err = modelClient.CreateEntity(appCtx.Context, &modelpb.CreateEntityRequest{
539+
Entity: localEntities[entity],
540+
})
541+
}
542+
return err
543+
})
491544
}
545+
// Need to wait for entities to be added before adding any
546+
// relationships that might reference them.
547+
errs = append(errs, addEntitiesPool.Wait())
492548

493549
// Add relationships.
550+
addRelationshipsPool := pool.New().WithErrors()
494551
relationshipsToBeAdded := localRelationshipKeys.Difference(remoteRelationshipKeys)
495552
for relationship := range relationshipsToBeAdded.Iter() {
496-
if printMode {
497-
fmt.Printf("add relationship: %s\n", relationship)
498-
}
499-
if !dryRunMode {
500-
_, err := modelClient.CreateRelationship(appCtx.Context, &modelpb.CreateRelationshipRequest{
501-
Relationship: relationship.ToProto(),
502-
})
503-
if err != nil {
504-
errs = append(errs, err)
553+
addRelationshipsPool.Go(func() error {
554+
if printMode {
555+
fmt.Printf("add relationship: %s\n", relationship)
505556
}
506-
}
507-
}
508-
509-
// Update entities.
510-
entitiesInCommon := localEntityKeys.Intersect(remoteEntityKeys)
511-
for entity := range entitiesInCommon.Iter() {
512-
if nmtsEntitiesAreEquivalent(localEntities[entity], remoteEntities[entity]) {
513-
continue
514-
}
515-
if printMode {
516-
fmt.Printf("update entity: %s\n", entity)
517-
}
518-
if !dryRunMode {
519-
_, err := modelClient.UpdateEntity(appCtx.Context, &modelpb.UpdateEntityRequest{
520-
Entity: localEntities[entity],
521-
})
522-
if err != nil {
523-
errs = append(errs, err)
557+
var err error
558+
if !dryRunMode {
559+
_, err = modelClient.CreateRelationship(appCtx.Context, &modelpb.CreateRelationshipRequest{
560+
Relationship: relationship.ToProto(),
561+
})
524562
}
525-
}
563+
return err
564+
})
526565
}
566+
errs = append(errs, addRelationshipsPool.Wait())
527567

528568
return errors.Join(errs...)
529569
}

0 commit comments

Comments
 (0)