<> <> <> <> DIRECTORY BasicTime, Commander, ComputeControllerImpl, ComputeControllerInternal, ComputeServerController, ComputeServer, ComputeServerInternal, DFUtilities, FS, IO, PrincOps, PrincOpsUtils, Process, PupDefs, PupTypes, Rope, RPC, SummonerControllerControl; ComputeControllerPackagesImpl: CEDAR MONITOR LOCKS ComputeControllerImpl.LOCK IMPORTS BasicTime, Commander, ComputeControllerImpl, ComputeControllerInternal, ComputeServerInternal, DFUtilities, FS, IO, Process, Rope EXPORTS ComputeServerController SHARES ComputeControllerImpl = BEGIN ROPE: TYPE = Rope.ROPE; ServerStatus: TYPE = ComputeControllerInternal.ServerStatus; NoticeNewPackageCondition: CONDITION; NoticeNewPackage: PUBLIC ENTRY PROC [package: RPC.ShortROPE] RETURNS [error: BOOL _ FALSE, tryDifferentController: BOOL _ FALSE, msg: ROPE _ NIL]= { ENABLE UNWIND => NULL; statusList: LIST OF ServerStatus; packageListInStream: IO.STREAM; packageListGlobalName: ROPE _ NIL; packageListOutStream: IO.STREAM; packageListTempName: ROPE _ NIL; foundItem: BOOL _ FALSE; fullFName: ROPE; fsErrMsg: ROPE; cp: FS.ComponentPositions; dirOmitted: BOOLEAN; dfPrefix: ROPE; shortPackage: ROPE _ NIL; shortPackageAndDF: ROPE _ NIL; packageDFDate: BasicTime.GMT _ BasicTime.nullGMT; sawDir: BOOL _ FALSE; blankAfterDir: BOOL _ FALSE; lastDir: REF DFUtilities.DirectoryItem _ NIL; wroteDir: BOOL _ FALSE; defaultDirectory: REF DFUtilities.DirectoryItem _ NIL ; whiteItem: REF DFUtilities.WhiteSpaceItem _ NEW[DFUtilities.WhiteSpaceItem _ [1]]; writeUpdatedItem: PROC[] = { file: REF DFUtilities.FileItem; file _ NEW[DFUtilities.FileItem _ [ name: shortPackageAndDF, -- a short name date: [explicit, packageDFDate], verifyRoot: FALSE]]; IF lastDir = NIL OR ~Rope.Equal[lastDir.path1, dfPrefix, FALSE] THEN { dir: REF DFUtilities.DirectoryItem _ NEW [DFUtilities.DirectoryItem _ [ path1: dfPrefix, path2: NIL, path2IsCameFrom: FALSE, exported: FALSE, readOnly: FALSE ]]; DFUtilities.WriteItemToStream[out: packageListOutStream, item: whiteItem]; DFUtilities.WriteItemToStream[out: packageListOutStream, item: dir]; DFUtilities.WriteItemToStream[out: packageListOutStream, item: whiteItem]; lastDir _ dir; }; DFUtilities.WriteItemToStream[out: packageListOutStream, item: file]; }; DoOneItem: DFUtilities.ProcessItemProc = { <> errors, warnings, filesActedUpon: INT _ 0; WITH item SELECT FROM dir: REF DFUtilities.DirectoryItem => { IF lastDir = NIL OR ~Rope.Equal[lastDir.path1, dir.path1, FALSE] THEN { wroteDir _ FALSE; lastDir _ dir; }; }; comment: REF DFUtilities.CommentItem => { DFUtilities.WriteItemToStream[out: packageListOutStream, item: comment]; }; white: REF DFUtilities.WhiteSpaceItem => { }; file: REF DFUtilities.FileItem => { shortName: ROPE = Rope.Substr[file.name, 0, Rope.Index[s1: file.name, s2: "!"]]; packageDFDate: BasicTime.GMT _ BasicTime.nullGMT; currentDFDate: BasicTime.GMT _ BasicTime.nullGMT; IF ~wroteDir THEN { wroteDir _ TRUE; IF lastDir = NIL THEN lastDir _ defaultDirectory; DFUtilities.WriteItemToStream[out: packageListOutStream, item: whiteItem]; DFUtilities.WriteItemToStream[out: packageListOutStream, item: lastDir]; DFUtilities.WriteItemToStream[out: packageListOutStream, item: whiteItem]; }; IF Rope.Equal[shortPackageAndDF, shortName, FALSE] THEN { writeUpdatedItem[]; foundItem _ TRUE; } ELSE { DFUtilities.WriteItemToStream[out: packageListOutStream, item: file]; }; }; ENDCASE; }; { ENABLE UNWIND => { IF packageListInStream # NIL THEN packageListInStream.Close[! FS.Error => CONTINUE]; IF packageListOutStream # NIL THEN packageListOutStream.Close[! FS.Error => CONTINUE]; FS.Delete[name: packageListTempName ! FS.Error => CONTINUE]; }; IF package.IsEmpty[] THEN RETURN [ TRUE, FALSE, "null package name"]; IF ~ComputeControllerInternal.IAmTheController THEN RETURN [ FALSE, TRUE, "controller has moved"]; WHILE ComputeControllerInternal.IAmTheController AND BasicTime.Period[ComputeControllerInternal.TimeIBecameTheController, BasicTime.Now[]] < 22 DO WAIT NoticeNewPackageCondition; ENDLOOP; IF ~ComputeControllerInternal.IAmTheController THEN RETURN [ FALSE, TRUE, "controller has moved"]; [fullFName: fullFName, cp: cp, dirOmitted: dirOmitted] _ FS.ExpandName[name: package, wDir: NIL ! FS.Error => GOTO badPackageName ]; shortPackage _ fullFName.Substr[cp.base.start, cp.base.length]; shortPackageAndDF _ Rope.Concat[shortPackage, ".df"]; dfPrefix _ fullFName.Substr[0, cp.base.start]; defaultDirectory _ NEW [DFUtilities.DirectoryItem _ [ path1: dfPrefix, path2: NIL, path2IsCameFrom: FALSE, exported: FALSE, readOnly: FALSE ]]; [created: packageDFDate] _ FS.FileInfo[name: package, remoteCheck: TRUE ! FS.Error => GOTO noDFFile]; packageListGlobalName _ Rope.Concat[ComputeServerInternal.RemoteCommandDir, "PackageList"]; packageListInStream _ FS.StreamOpen[packageListGlobalName ! FS.Error => GOTO cantOpenPackageList]; packageListTempName _ Rope.Concat[ComputeServerInternal.LocalCommandDir, "PackageList.temp"]; packageListOutStream _ FS.StreamOpen[fileName: packageListTempName, accessOptions: $create]; DFUtilities.ParseFromStream[packageListInStream, DoOneItem ! DFUtilities.SyntaxError => GOTO syntaxErrorInPackageList]; IF ~foundItem THEN writeUpdatedItem[]; packageListInStream.Close[! FS.Error => CONTINUE]; packageListOutStream.Close[! FS.Error => CONTINUE]; [] _ FS.Copy[from: packageListTempName, to: packageListGlobalName, attach: FALSE ! FS.Error => { fsErrMsg _ error.explanation; GOTO cantCopyToServer}]; FS.Delete[name: packageListTempName ! FS.Error => CONTINUE]; IF ~ComputeControllerInternal.IAmTheController THEN RETURN [ FALSE, TRUE, "controller has moved"]; FOR statusList _ ComputeControllerInternal.ServerStatusList, statusList.rest UNTIL statusList = NIL DO statusList.first.newPackage _ TRUE; ENDLOOP; EXITS cantOpenPackageList => RETURN [ TRUE, FALSE, "controller could not open package list"]; noDFFile => RETURN [ TRUE, FALSE, "controller could not open specified df file - "]; syntaxErrorInPackageList => RETURN [ TRUE, FALSE, "controller could not parse the package list - call an implementor"]; badPackageName => RETURN [ TRUE, FALSE, "bad package df file name"]; cantCopyToServer => RETURN [ TRUE, FALSE, Rope.Concat["could not copy new package list to the file server because ", fsErrMsg]]; }; }; RemoveOldPackage: PUBLIC ENTRY PROC [package: RPC.ShortROPE] RETURNS [error: BOOL, tryDifferentController: BOOL, msg: Rope.ROPE] = { ENABLE UNWIND => NULL; statusList: LIST OF ServerStatus; packageListInStream: IO.STREAM; packageListGlobalName: ROPE _ NIL; packageListOutStream: IO.STREAM; packageListTempName: ROPE _ NIL; foundItem: BOOL _ FALSE; fullFName: ROPE; cp: FS.ComponentPositions; dirOmitted: BOOLEAN; dfPrefix: ROPE; shortPackage: ROPE _ NIL; shortPackageAndDF: ROPE _ NIL; wroteDir: BOOL _ FALSE; lastDir: REF DFUtilities.DirectoryItem _ NIL; defaultDirectory: REF DFUtilities.DirectoryItem _ NIL ; whiteItem: REF DFUtilities.WhiteSpaceItem _ NEW[DFUtilities.WhiteSpaceItem _ [1]]; DoOneItem: DFUtilities.ProcessItemProc = { <> errors, warnings, filesActedUpon: INT _ 0; WITH item SELECT FROM dir: REF DFUtilities.DirectoryItem => { IF lastDir = NIL OR ~Rope.Equal[lastDir.path1, dir.path1, FALSE] THEN { <> wroteDir _ FALSE; lastDir _ dir; }; }; comment: REF DFUtilities.CommentItem => { DFUtilities.WriteItemToStream[out: packageListOutStream, item: comment]; }; white: REF DFUtilities.WhiteSpaceItem => { DFUtilities.WriteItemToStream[out: packageListOutStream, item: white]; }; file: REF DFUtilities.FileItem => { shortName: ROPE = Rope.Substr[file.name, 0, Rope.Index[s1: file.name, s2: "!"]]; currentDFDate: BasicTime.GMT _ BasicTime.nullGMT; IF Rope.Equal[shortPackageAndDF, shortName, FALSE] THEN { foundItem _ TRUE; } ELSE { IF ~wroteDir THEN { wroteDir _ TRUE; IF lastDir = NIL THEN lastDir _ defaultDirectory; DFUtilities.WriteItemToStream[out: packageListOutStream, item: whiteItem]; DFUtilities.WriteItemToStream[out: packageListOutStream, item: lastDir]; DFUtilities.WriteItemToStream[out: packageListOutStream, item: whiteItem]; }; DFUtilities.WriteItemToStream[out: packageListOutStream, item: file]; }; }; ENDCASE; }; { ENABLE UNWIND => { IF packageListInStream # NIL THEN packageListInStream.Close[! FS.Error => CONTINUE]; IF packageListOutStream # NIL THEN packageListOutStream.Close[! FS.Error => CONTINUE]; FS.Delete[name: packageListTempName ! FS.Error => CONTINUE]; }; IF package.IsEmpty[] THEN RETURN [ TRUE, FALSE, "null package name"]; IF ~ComputeControllerInternal.IAmTheController THEN RETURN [ FALSE, TRUE, "controller has moved"]; WHILE ComputeControllerInternal.IAmTheController AND BasicTime.Period[ComputeControllerInternal.TimeIBecameTheController, BasicTime.Now[]] < 22 DO WAIT NoticeNewPackageCondition; ENDLOOP; IF ~ComputeControllerInternal.IAmTheController THEN RETURN [ FALSE, TRUE, "controller has moved"]; [fullFName: fullFName, cp: cp, dirOmitted: dirOmitted] _ FS.ExpandName[name: package, wDir: NIL ! FS.Error => GOTO badPackageName ]; shortPackage _ fullFName.Substr[cp.base.start, cp.base.length]; shortPackageAndDF _ Rope.Concat[shortPackage, ".df"]; dfPrefix _ fullFName.Substr[0, cp.base.start]; defaultDirectory _ NEW [DFUtilities.DirectoryItem _ [ path1: dfPrefix, path2: NIL, path2IsCameFrom: FALSE, exported: FALSE, readOnly: FALSE ]]; packageListGlobalName _ Rope.Concat[ComputeServerInternal.RemoteCommandDir, "PackageList"]; packageListInStream _ FS.StreamOpen[packageListGlobalName ! FS.Error => GOTO cantOpenPackageList]; packageListTempName _ Rope.Concat[ComputeServerInternal.LocalCommandDir, "PackageList.temp"]; packageListOutStream _ FS.StreamOpen[fileName: packageListTempName, accessOptions: $create]; DFUtilities.ParseFromStream[packageListInStream, DoOneItem ! DFUtilities.SyntaxError => GOTO syntaxErrorInPackageList]; packageListInStream.Close[! FS.Error => CONTINUE]; packageListOutStream.Close[! FS.Error => CONTINUE]; IF ~foundItem THEN { FS.Delete[name: packageListTempName ! FS.Error => CONTINUE]; RETURN [ TRUE, FALSE, "package not found"] }; [] _ FS.Copy[from: packageListTempName, to: packageListGlobalName, attach: FALSE]; FS.Delete[name: packageListTempName ! FS.Error => CONTINUE]; IF ~ComputeControllerInternal.IAmTheController THEN RETURN [ FALSE, TRUE, "controller has moved"]; FOR statusList _ ComputeControllerInternal.ServerStatusList, statusList.rest UNTIL statusList = NIL DO statusList.first.newPackage _ TRUE; ENDLOOP; EXITS cantOpenPackageList => RETURN [ TRUE, FALSE, "controller could not open package list"]; syntaxErrorInPackageList => RETURN [ TRUE, FALSE, "controller could not parse the package list - call an implementor"]; badPackageName => RETURN [ TRUE, FALSE, "bad package df file name"]; }; }; <> SetGrabController: Commander.CommandProc = { ComputeControllerInternal.GrabController _ TRUE; }; Commander.Register[key: "///Commands/SummonerBecomeController", proc: SetGrabController, doc: "Try to force the Compute Server Controller to this machine"]; TRUSTED {Process.InitializeCondition[@NoticeNewPackageCondition, Process.SecondsToTicks[1]];}; END. <> <> <<>>