services/device/internal/impl: tidy automatically
This change completes tidying support in the device manager: tidying
runs at regular intervals automatically.
Change-Id: I0f96466c488897cfd01ac0414e607d17da45dedd
diff --git a/services/device/internal/impl/device_service.go b/services/device/internal/impl/device_service.go
index 24641e1..68a4d76 100644
--- a/services/device/internal/impl/device_service.go
+++ b/services/device/internal/impl/device_service.go
@@ -110,6 +110,7 @@
disp *dispatcher
uat BlessingSystemAssociationStore
securityAgent *securityAgentState
+ tidying chan<- tidyRequests
}
// Version info for this device manager binary. Increment as appropriate when the binary changes.
@@ -677,21 +678,8 @@
}}, nil
}
-// tidyHarness runs device manager cleanup operations
-func (s *deviceService) tidyHarness(ctx *context.T) error {
- now := MockableNow()
-
- if err := pruneDeletedInstances(ctx, s.config.Root, now); err != nil {
- return err
- }
-
- if err := pruneUninstalledInstallations(ctx, s.config.Root, now); err != nil {
- return err
- }
-
- return pruneOldLogs(ctx, s.config.Root, now)
-}
-
-func (s *deviceService) TidyNow(ctx *context.T, call rpc.ServerCall) error {
- return s.tidyHarness(ctx)
+func (s *deviceService) TidyNow(ctx *context.T, _ rpc.ServerCall) error {
+ ec := make(chan error)
+ s.tidying <- tidyRequests{ctx: ctx, bc: ec}
+ return <-ec
}
diff --git a/services/device/internal/impl/dispatcher.go b/services/device/internal/impl/dispatcher.go
index 62d4787..16f81d0 100644
--- a/services/device/internal/impl/dispatcher.go
+++ b/services/device/internal/impl/dispatcher.go
@@ -43,6 +43,8 @@
testMode bool
// reap is the app process monitoring subsystem.
reap *reaper
+ // tidying is the automatic state tidying subsystem.
+ tidying chan<- tidyRequests
}
// dispatcher holds the state of the device manager dispatcher.
@@ -125,6 +127,7 @@
updating: newUpdatingState(),
restartHandler: restartHandler,
testMode: testMode,
+ tidying: newTidyingDaemon(config.Root),
},
config: config,
uat: uat,
@@ -278,6 +281,7 @@
disp: d,
uat: d.uat,
securityAgent: d.internal.securityAgent,
+ tidying: d.internal.tidying,
})
return receiver, auth, nil
case appsSuffix:
diff --git a/services/device/internal/impl/tidyup.go b/services/device/internal/impl/tidyup.go
index 2ae0850..3b9c3ca 100644
--- a/services/device/internal/impl/tidyup.go
+++ b/services/device/internal/impl/tidyup.go
@@ -14,6 +14,8 @@
"v.io/v23/context"
"v.io/v23/services/device"
"v.io/v23/verror"
+
+ "v.io/x/lib/vlog"
)
// This file contains the various routines that the device manager uses
@@ -25,6 +27,10 @@
return fi.ModTime().Add(aboutOneDay).Before(now)
}
+// AutomaticTidyingInterval defaults to 1 day.
+// Settable for tests.
+var AutomaticTidyingInterval = time.Hour * 24
+
func shouldDelete(idir, suffix string, now time.Time) (bool, error) {
fi, err := os.Stat(filepath.Join(idir, suffix))
if err != nil {
@@ -205,3 +211,48 @@
}
return processErrors(ctx, allerrors)
}
+
+// tidyHarness runs device manager cleanup operations
+func tidyHarness(ctx *context.T, root string) error {
+ now := MockableNow()
+
+ if err := pruneDeletedInstances(ctx, root, now); err != nil {
+ return err
+ }
+
+ if err := pruneUninstalledInstallations(ctx, root, now); err != nil {
+ return err
+ }
+
+ return pruneOldLogs(ctx, root, now)
+}
+
+// tidyDaemon runs in a Go routine, processing requests to tidy
+// or tidying on a schedule.
+func tidyDaemon(c <-chan tidyRequests, root string) {
+ for {
+ select {
+ case req, ok := <-c:
+ if !ok {
+ return
+ }
+ req.bc <- tidyHarness(req.ctx, root)
+ case <-time.After(AutomaticTidyingInterval):
+ if err := tidyHarness(nil, root); err != nil {
+ vlog.Errorf("tidyDaemon failed to tidy: %v", err)
+ }
+ }
+
+ }
+}
+
+type tidyRequests struct {
+ ctx *context.T
+ bc chan<- error
+}
+
+func newTidyingDaemon(root string) chan<- tidyRequests {
+ c := make(chan tidyRequests)
+ go tidyDaemon(c, root)
+ return c
+}