Skip to content

Commit bb80a78

Browse files
authored
Merge pull request #114 from trimble-oss/side_band_sync_pull
Side band sync pull
2 parents b9ebf04 + 2e0dbfe commit bb80a78

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

flow/flow.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ type FlowContext interface {
185185
GetFlowStateSyncFilterRaw() string
186186
GetFlowSyncFilters() []string
187187
SetFlowSyncFilter(string)
188+
GetPullOnceMu() *sync.Mutex
188189
GetFlowHeader() *FlowHeaderType
189190
NewFlowStateUpdate(string, string) FlowStateUpdate
190191
GetCurrentFlowStateUpdateByDataSource(string) any

flow/process_genericflow.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,12 @@ func ProcessTableConfigurations(tfmContext FlowMachineContext, tfContext FlowCon
274274
}
275275

276276
func ProcessFlowStatesForInterval(tfContext FlowContext, tfmContext FlowMachineContext, flowDefinitionContext *FlowLibraryContext, regionList []string) int {
277+
// Acquire the pullOnceMu so that synchronous ExecuteFilteredPullOnce calls block
278+
// all async push/pull activity for this flow until they complete.
279+
mu := tfContext.GetPullOnceMu()
280+
mu.Lock()
281+
defer mu.Unlock()
282+
277283
if tfContext.GetFlowStateState() == 3 {
278284
tfContext.SetRestart(false)
279285
tfmContext.SetPermissionUpdate(tfContext)
@@ -468,3 +474,66 @@ func ProcessFlowStatesForInterval(tfContext FlowContext, tfmContext FlowMachineC
468474
}
469475
return 0
470476
}
477+
478+
// ExecuteFilteredPullOnce synchronously performs a pullonce for a flow filtered by
479+
// the given syncFilter value. It acquires the flow's pullOnceMu before setting state,
480+
// ensuring that no async push/pull activity races with the synchronous operation.
481+
func ExecuteFilteredPullOnce(tfmContext FlowMachineContext, tfContext FlowContext, syncFilter string) {
482+
flowDefinitionContext := tfContext.GetFlowLibraryContext()
483+
if flowDefinitionContext == nil {
484+
return
485+
}
486+
487+
// Acquire the mutex before mutating state so the async path cannot race with us.
488+
mu := tfContext.GetPullOnceMu()
489+
mu.Lock()
490+
defer mu.Unlock()
491+
492+
tfContext.SetFlowSyncFilter(syncFilter)
493+
tfContext.SetFlowSyncMode("pullonce")
494+
495+
var tableIndexKey string
496+
if flowDefinitionContext.GetTableIndexColumnNames != nil {
497+
if keys := flowDefinitionContext.GetTableIndexColumnNames(); len(keys) == 1 {
498+
tableIndexKey = keys[0]
499+
}
500+
}
501+
if len(tableIndexKey) == 0 {
502+
tfmContext.Log("ExecuteFilteredPullOnce: missing GetTableIndexColumnNames", nil)
503+
return
504+
}
505+
506+
tableConfigurations, err := tableConfigurationFlowPullRemote(tfmContext, tfContext)
507+
if err != nil {
508+
tfmContext.Log("ExecuteFilteredPullOnce: error pulling configurations", err)
509+
return
510+
}
511+
512+
var filtered []map[string]any
513+
for _, filter := range tfContext.GetFlowSyncFilters() {
514+
for _, table := range tableConfigurations {
515+
if filter == table[tableIndexKey].(string) {
516+
filtered = append(filtered, table)
517+
}
518+
}
519+
}
520+
tableConfigurations = filtered
521+
522+
for _, table := range tableConfigurations {
523+
rows, _ := tfmContext.CallDBQuery(tfContext, flowDefinitionContext.GetTableConfigurationById(tfContext.GetFlowHeader().SourceAlias, tfContext.GetFlowHeader().FlowName(), table[tableIndexKey].(string)), nil, false, "SELECT", nil, "")
524+
if len(rows) == 0 {
525+
tfmContext.CallDBQuery(tfContext, flowDefinitionContext.GetTableConfigurationInsert(table, tfContext.GetFlowHeader().SourceAlias, tfContext.GetFlowHeader().FlowName()), nil, true, "INSERT", []FlowNameType{tfContext.GetFlowHeader().FlowNameType()}, "")
526+
} else {
527+
for _, value := range rows {
528+
if CompareRows(table, flowDefinitionContext.GetTableMapFromArray(value)) {
529+
continue
530+
}
531+
tfmContext.CallDBQuery(tfContext, flowDefinitionContext.GetTableConfigurationUpdate(table, tfContext.GetFlowHeader().SourceAlias, tfContext.GetFlowHeader().FlowName()), nil, true, "UPDATE", []FlowNameType{tfContext.GetFlowHeader().FlowNameType()}, "")
532+
}
533+
}
534+
}
535+
536+
tfContext.SetFlowSyncFilter("")
537+
tfContext.SetFlowSyncMode("pullcomplete")
538+
tfContext.PushState("flowStateReceiver", tfContext.NewFlowStateUpdate("2", "pullcomplete"))
539+
}

0 commit comments

Comments
 (0)