-- Coordinator.mesa -- Defines the volatile state of a coordinator. -- Last edited by -- MBrown on January 30, 1984 11:51:40 am PST DIRECTORY AlpineEnvironment, AlpineImport USING [Handle], AlpineInternal USING [LogRecordID, nullLogRecordID], BasicTime USING [GMT], RPC USING [maxShortStringLength]; Coordinator: DEFINITIONS LOCKS c USING c: Handle = BEGIN Object: TYPE = MONITORED RECORD [ transID: AlpineEnvironment.TransID _ TRASH, --immutable-- beginRecord: AlpineInternal.LogRecordID _ AlpineInternal.nullLogRecordID, --immutable-- state: State _ active, --increases monotonically from active to complete outcome: Outcome _ unknown, -- Changes to abort or commit during state transition collecting -> completing. finishInProgress: BOOL _ FALSE, -- A process that sets this TRUE is responsible for finishing the transaction. aWorkerBecameReady: BOOL _ FALSE, -- TRUE iff some worker returns "ready" from WorkerPrepare call. workers: WorkerHandle _ NIL, -- Elements added only when state = active. resultsReturned: CONDITION, -- Finish process waits here for remote calls to return, or for timeout --in order to delay sending new calls. forceRecord: AlpineInternal.LogRecordID _ AlpineInternal.nullLogRecordID, -- ID of log record following last-written coordinator log record next: Handle _ nullHandle --CoordinatorMap data structure ]; Handle: TYPE = REF Object; nullHandle: Handle = NIL; State: TYPE = {active, collecting, completing, complete}; Outcome: TYPE = AlpineEnvironment.Outcome --{abort, commit, unknown}--; WorkerObject: TYPE = RECORD [ worker: AlpineImport.Handle, --immutable-- state: WorkerState _ active, --increases monotonically from active to complete-- communicationTrouble: BOOL _ FALSE, callInProgress: Call _ none, --communication in progress with worker-- resultsOfMostRecentCall: Results _ [none, none[]], timeForNextCall: BasicTime.GMT _ TRASH, -- meaningful only if communicationTrouble lastPrepareResult: Results _ [none, none[]], lastFinishResult: Results _ [none, none[]] ]; WorkerHandle: TYPE = LIST OF WorkerObject; WorkerState: TYPE = { active, ready, complete }; Call: TYPE = { none, prepare, finish }; Results: TYPE = RECORD [ communicationError: CommunicationError, body: SELECT call: Call FROM none => [], prepare => [prepareResult: AlpineEnvironment.WorkerState], finish => [] ENDCASE ]; CommunicationError: TYPE = { none, bindingFailed, callFailed, busy }; -- bindingFailed means that no call was made -- callFailed means that call may or may not have been made -- busy is equivalent to callFailed, but retrying is more likely to succeed. -- Format of persistent coordinator state. -- Note that coordinatorBegin and coordinatorComplete log records contain no information --other than the transaction ID, so we don't define structures for them here. RegisterWorkerLogRep: TYPE = MACHINE DEPENDENT RECORD [ worker: StrBody]; CompletingLogRep: TYPE = MACHINE DEPENDENT RECORD [ outcome: AlpineEnvironment.CommitOrAbort]; StrBody: TYPE = MACHINE DEPENDENT RECORD [ length: CARDINAL _ 0, maxLength: CARDINAL _ RPC.maxShortStringLength, text: PACKED ARRAY[0..RPC.maxShortStringLength) OF CHAR]; END.