@@ -24,6 +24,7 @@ import (
24
24
"github.com/ovn-org/libovsdb/model"
25
25
"github.com/ovn-org/libovsdb/ovsdb"
26
26
"github.com/ovn-org/libovsdb/ovsdb/serverdb"
27
+ "github.com/ovn-org/libovsdb/util"
27
28
)
28
29
29
30
// Constants defined for libovsdb
@@ -260,15 +261,7 @@ func (o *ovsdbClient) connect(ctx context.Context, reconnect bool) error {
260
261
}
261
262
262
263
if ! connected {
263
- if len (connectErrors ) == 1 {
264
- return connectErrors [0 ]
265
- }
266
- var combined []string
267
- for _ , e := range connectErrors {
268
- combined = append (combined , e .Error ())
269
- }
270
-
271
- return fmt .Errorf ("unable to connect to any endpoints: %s" , strings .Join (combined , ". " ))
264
+ return util .CombineErrors (connectErrors , "unable to connect to any endpoints" )
272
265
}
273
266
274
267
// if we're reconnecting, re-start all the monitors
@@ -371,8 +364,6 @@ func (o *ovsdbClient) tryEndpoint(ctx context.Context, u *url.URL) (string, erro
371
364
return "" , err
372
365
}
373
366
db .api = newAPI (db .cache , o .logger )
374
- } else {
375
- db .cache .Purge (db .model )
376
367
}
377
368
db .cacheMutex .Unlock ()
378
369
}
@@ -809,6 +800,51 @@ func (o *ovsdbClient) Monitor(ctx context.Context, monitor *Monitor) (MonitorCoo
809
800
return cookie , o .monitor (ctx , cookie , false , monitor )
810
801
}
811
802
803
+ func (db * database ) getMonitorTableConditions (tm TableMonitor ) (* ovsdb.Condition , error ) {
804
+ model , err := db .model .NewModel (tm .Table )
805
+ if err != nil {
806
+ return nil , err
807
+ }
808
+ info , err := db .model .NewModelInfo (model )
809
+ if err != nil {
810
+ return nil , err
811
+ }
812
+ return db .model .Mapper .NewCondition (info , tm .Condition .Field , tm .Condition .Function , tm .Condition .Value )
813
+ }
814
+
815
+ // purge removes all rows from the row cache that match the monitor
816
+ func (o * ovsdbClient ) purge (db * database , monitor * Monitor ) {
817
+ if len (monitor .Tables ) == 0 {
818
+ db .cache .Purge (db .model )
819
+ return
820
+ }
821
+
822
+ var err error
823
+ for _ , tm := range monitor .Tables {
824
+ if monitor .Method == ovsdb .ConditionalMonitorSinceRPC {
825
+ var cond * ovsdb.Condition
826
+ cond , err = db .getMonitorTableConditions (tm )
827
+ if err != nil {
828
+ break
829
+ }
830
+ err = db .cache .PurgeTableRows (db .model , tm .Table , []ovsdb.Condition {* cond })
831
+ if err != nil {
832
+ break
833
+ }
834
+ } else {
835
+ err = db .cache .PurgeTable (db .model , tm .Table )
836
+ if err != nil {
837
+ break
838
+ }
839
+ }
840
+ }
841
+
842
+ if err != nil {
843
+ o .logger .V (3 ).Error (err , "failed to purge database" )
844
+ db .cache .Purge (db .model )
845
+ }
846
+ }
847
+
812
848
//gocyclo:ignore
813
849
// monitor must only be called with a lock on monitorsMutex
814
850
func (o * ovsdbClient ) monitor (ctx context.Context , cookie MonitorCookie , reconnecting bool , monitor * Monitor ) error {
@@ -859,12 +895,7 @@ func (o *ovsdbClient) monitor(ctx context.Context, cookie MonitorCookie, reconne
859
895
860
896
var args []interface {}
861
897
if monitor .Method == ovsdb .ConditionalMonitorSinceRPC {
862
- // FIXME: We should pass the monitor.LastTransactionID here
863
- // But that would require delaying clearing the cache until
864
- // after the monitors have been re-established - the logic
865
- // would also need to be different for monitor and monitor_cond
866
- // as we must always clear the cache in that instance
867
- args = ovsdb .NewMonitorCondSinceArgs (dbName , cookie , requests , emptyUUID )
898
+ args = ovsdb .NewMonitorCondSinceArgs (dbName , cookie , requests , monitor .LastTransactionID )
868
899
} else {
869
900
args = ovsdb .NewMonitorArgs (dbName , cookie , requests )
870
901
}
@@ -873,18 +904,24 @@ func (o *ovsdbClient) monitor(ctx context.Context, cookie MonitorCookie, reconne
873
904
874
905
switch monitor .Method {
875
906
case ovsdb .MonitorRPC :
907
+ o .purge (db , monitor )
876
908
var reply ovsdb.TableUpdates
877
909
err = o .rpcClient .CallWithContext (ctx , monitor .Method , args , & reply )
878
910
tableUpdates = reply
879
911
case ovsdb .ConditionalMonitorRPC :
912
+ o .purge (db , monitor )
880
913
var reply ovsdb.TableUpdates2
881
914
err = o .rpcClient .CallWithContext (ctx , monitor .Method , args , & reply )
882
915
tableUpdates = reply
883
916
case ovsdb .ConditionalMonitorSinceRPC :
884
917
var reply ovsdb.MonitorCondSinceReply
885
918
err = o .rpcClient .CallWithContext (ctx , monitor .Method , args , & reply )
886
- if err == nil && reply .Found {
887
- monitor .LastTransactionID = reply .LastTransactionID
919
+ if err == nil {
920
+ if reply .Found {
921
+ monitor .LastTransactionID = reply .LastTransactionID
922
+ } else {
923
+ o .purge (db , monitor )
924
+ }
888
925
}
889
926
tableUpdates = reply .Updates
890
927
default :
0 commit comments