github.com/Cloud-Foundations/Dominator@v0.3.4/sub/rpcd/api.go (about) 1 package rpcd 2 3 import ( 4 "io" 5 "sync" 6 "time" 7 8 "github.com/Cloud-Foundations/Dominator/lib/goroutine" 9 "github.com/Cloud-Foundations/Dominator/lib/log" 10 "github.com/Cloud-Foundations/Dominator/lib/rateio" 11 "github.com/Cloud-Foundations/Dominator/lib/srpc" 12 "github.com/Cloud-Foundations/Dominator/lib/srpc/serverutil" 13 "github.com/Cloud-Foundations/Dominator/lib/stringutil" 14 proto "github.com/Cloud-Foundations/Dominator/proto/sub" 15 "github.com/Cloud-Foundations/Dominator/sub/scanner" 16 "github.com/Cloud-Foundations/tricorder/go/tricorder" 17 "github.com/Cloud-Foundations/tricorder/go/tricorder/units" 18 ) 19 20 const ( 21 disruptionManagerCancel = "cancel" 22 disruptionManagerCheck = "check" 23 disruptionManagerRequest = "request" 24 ) 25 26 type Config struct { 27 DisruptionManager string 28 NetworkBenchmarkFilename string 29 NoteGeneratorCommand string 30 ObjectsDirectoryName string 31 OldTriggersFilename string 32 RootDirectoryName string 33 SubConfiguration proto.Configuration 34 } 35 36 type Params struct { 37 DisableScannerFunction func(disableScanner bool) 38 FileSystemHistory *scanner.FileSystemHistory 39 Logger log.DebugLogger 40 NetworkReaderContext *rateio.ReaderContext 41 RescanObjectCacheFunction func() 42 ScannerConfiguration *scanner.Configuration 43 SubdDirectory string 44 WorkdirGoroutine *goroutine.Goroutine 45 } 46 47 type rpcType struct { 48 config Config 49 params Params 50 systemGoroutine *goroutine.Goroutine 51 *serverutil.PerUserMethodLimiter 52 disruptionManagerControl chan<- bool // True: request; false: cancel. 53 ownerUsers map[string]struct{} 54 rwLock sync.RWMutex // Protect everything below. 55 disruptionState proto.DisruptionState 56 getFilesLock sync.Mutex 57 fetchInProgress bool // Fetch() & Update() mutually exclusive. 58 updateInProgress bool 59 startTimeNanoSeconds int32 // For Fetch() or Update(). 60 startTimeSeconds int64 61 initialImageName string 62 lastFetchError error 63 lastNote string 64 lastSuccessfulImageName string 65 lastUpdateError error 66 lastUpdateHadTriggerFailures bool 67 lastWriteError string 68 lockedBy *srpc.Conn 69 lockedUntil time.Time 70 } 71 72 type addObjectsHandlerType struct { 73 objectsDir string 74 scannerConfiguration *scanner.Configuration 75 logger log.Logger 76 rpcObj *rpcType 77 } 78 79 type HtmlWriter struct { 80 lastNote *string 81 lastSuccessfulImageName *string 82 } 83 84 func Setup(config Config, params Params) *HtmlWriter { 85 rpcObj := &rpcType{ 86 config: config, 87 params: params, 88 systemGoroutine: goroutine.New(), 89 initialImageName: readInitialImageFile(), 90 lastSuccessfulImageName: readPatchedImageFile(), 91 PerUserMethodLimiter: serverutil.NewPerUserMethodLimiter( 92 map[string]uint{ 93 "Poll": 1, 94 }), 95 } 96 rpcObj.startDisruptionManager() 97 rpcObj.ownerUsers = stringutil.ConvertListToMap( 98 config.SubConfiguration.OwnerUsers, false) 99 srpc.RegisterNameWithOptions("Subd", rpcObj, 100 srpc.ReceiverOptions{ 101 PublicMethods: []string{ 102 "GetConfiguration", 103 "Poll", 104 }}) 105 addObjectsHandler := &addObjectsHandlerType{ 106 objectsDir: config.ObjectsDirectoryName, 107 scannerConfiguration: params.ScannerConfiguration, 108 logger: params.Logger, 109 rpcObj: rpcObj, 110 } 111 srpc.RegisterName("ObjectServer", addObjectsHandler) 112 tricorder.RegisterMetric("/image-name", &rpcObj.lastSuccessfulImageName, 113 units.None, "name of the image for the last successful update") 114 if note, err := rpcObj.generateNote(); err != nil { 115 params.Logger.Println(err) 116 } else if note != "" { 117 rpcObj.lastNote = note 118 } 119 go rpcObj.startWriteProber() 120 return &HtmlWriter{ 121 lastNote: &rpcObj.lastNote, 122 lastSuccessfulImageName: &rpcObj.lastSuccessfulImageName, 123 } 124 } 125 126 func (hw *HtmlWriter) WriteHtml(writer io.Writer) { 127 hw.writeHtml(writer) 128 }