WalnutOpsNewMailImpl.mesa
Willie-Sue, January 6, 1986 6:14:27 pm PST
Donahue, August 5, 1985 2:36:34 pm PDT
Implementation of WalnutOps NewMail stuff
Copyright © 1985 by Xerox Corporation. All rights reserved.
Initialted by Willie-sue, February 7, 1985
Last Edited by: Donahue, December 11, 1984 8:51:42 pm PST
DIRECTORY
BasicTime USING [GMT, Now],
FS USING [Error],
IO USING [Error, STREAM],
Rope USING [ROPE],
WalnutDB -- USING lots -- ,
WalnutDefs USING [Error, dontCareMsgSetVersion, ServerInfo],
WalnutLog -- USING lots -- ,
WalnutMiscLog USING [GetNewMailLog, CloseNewMailLog],
WalnutOps,
WalnutOpsMonitorImpl,
WalnutOpsInternal USING [mailStream, newMailSomewhere,
CarefullyApply, CheckInProgress, CheckReport, CleanupAfterCopy, LongRunningApply,
ParseLog],
WalnutRegistryPrivate USING [NotifyForEvent];
WalnutOpsNewMailImpl: CEDAR MONITOR LOCKS walnutOpsMonitorImpl
IMPORTS
BasicTime, IO, FS,
walnutOpsMonitorImpl: WalnutOpsMonitorImpl,
WalnutDB, WalnutDefs, WalnutOps, WalnutOpsInternal,
WalnutLog, WalnutMiscLog, WalnutRegistryPrivate
EXPORTS WalnutOps
SHARES WalnutOpsMonitorImpl
= BEGIN
Types
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
Procedures
Adding new messages from grapevine to the database
used by newMail process
StartNewMail: PUBLIC ENTRY PROC[] RETURNS[newMailStream: IO.STREAM] = {
ENABLE UNWIND => NULL;
newMailLogLength: INT ← -1;
Gnml: PROC =
{ newMailLogLength ← WalnutDB.GetNewMailLogLength[] };
WalnutOpsInternal.CheckInProgress[];
IF WalnutOpsInternal.mailStream # NIL THEN RETURN[NIL];
WalnutOpsInternal.CarefullyApply[proc: Gnml, didUpdate: FALSE];
IF newMailLogLength = -1 THEN RETURN[NIL];
RETURN[WalnutOpsInternal.mailStream ← WalnutMiscLog.GetNewMailLog[newMailLogLength, -1]];
};
RecordNewMailInfo: PUBLIC ENTRY PROC[logLen: INT, server: ROPE, num: INT] = {
ENABLE UNWIND => NULL;
when: BasicTime.GMT;
Snml: PROC = {
now: INT ← WalnutDB.GetServerInfo[server] + num;
[] ← WalnutLog.RecordNewMailInfo[logLen, when ← BasicTime.Now[], server, now];
WalnutDB.SetNewMailInfo[logLen, when, server, now];
};
WalnutOpsInternal.CheckInProgress[];
WalnutOpsInternal.CarefullyApply[proc: Snml, didUpdate: TRUE];
WalnutOpsInternal.newMailSomewhere ← TRUE;
};
EndNewMail: PUBLIC ENTRY PROC = {
ENABLE UNWIND => NULL;
strm: STREAM ← WalnutOpsInternal.mailStream;
WalnutOpsInternal.CheckInProgress[];
WalnutOpsInternal.mailStream ← NIL;
IF strm # NIL THEN
WalnutMiscLog.CloseNewMailLog[ ! WalnutDefs.Error , IO.Error, FS.Error => CONTINUE];
IF WalnutOpsInternal.newMailSomewhere THEN
WalnutRegistryPrivate.NotifyForEvent[mailRead];
};
used by higher levels
GetNewMail: PUBLIC ENTRY PROC[
activeVersion: INT,
proc: PROC[msg, TOCentry: ROPE, startOfSubject: INT]]
RETURNS[responses: LIST OF WalnutOps.ServerInfo, complete: BOOL] = {
ENABLE UNWIND => NULL;
someEntries: BOOL;
Cml: PROC = {
IF activeVersion # WalnutDefs.dontCareMsgSetVersion THEN
[] ← WalnutDB.VerifyMsgSet[ [WalnutOps.ActiveMsgSetName, activeVersion] ];
someEntries ← WalnutDB.GetNewMailLogLength[] # 0;
};
Cml2: PROC[inProgress: BOOL] = {
fromPos: INT ← 0;
complete ← WalnutLog.PrepareToCopyTempLog[which: newMail, pagesAlreadyCopied: 0, reportProc: WalnutOpsInternal.CheckReport];
IF ~complete THEN RETURN;
IF ~inProgress THEN {
at: INT ← WalnutLog.StartCopyNewMail[].at;
WalnutDB.SetOpInProgressPos[at];
WalnutDB.SetCopyMailLogPos[at];
}
ELSE {
at: INT = WalnutDB.GetCopyMailLogPos[];
WalnutOpsInternal.CheckReport["\n Continue copying the newMailLog\n"];
[] ← WalnutLog.SetPosition[at];
[] ← WalnutLog.NextEntry[];  -- skip the copy entry
fromPos ← WalnutLog.LogLength[] - WalnutLog.NextAt[];
};
WalnutDB.SetAddingServerMsgs[TRUE];
WalnutLog.CopyTempLog[newMail, WalnutDB.GetCopyMailLogPos[], fromPos, WalnutOpsInternal.CheckReport];
-- raises error if problem
WalnutOpsInternal.CheckReport["\n"];
WalnutDB.SetParseLogInProgress[TRUE];
WalnutDB.SetParseLogPos[WalnutDB.GetOpInProgressPos[]];
WalnutDB.SetOpInProgressPos[-1];
};
Gnm: PROC = {
IF proc # NIL THEN WalnutDB.EnumerateUnacceptedMsgs[activeVersion, proc];
responses ← WalnutDB.EnumerateServers[];
};
WalnutOpsInternal.CheckInProgress[];
WalnutOpsInternal.CarefullyApply[Cml, FALSE];
IF WalnutOpsInternal.mailStream # NIL THEN RETURN[NIL, FALSE];  -- file is busy
IF someEntries THEN {
WalnutOpsInternal.LongRunningApply[Cml2];
IF complete THEN {
WalnutOpsInternal.CleanupAfterCopy[];
WalnutOpsInternal.CheckReport["Adding new mail to the database\n"];
[] ← WalnutOpsInternal.ParseLog[TRUE];  -- "see" messages
};
}
ELSE complete ← TRUE;
WalnutOpsInternal.CarefullyApply[Gnm, FALSE];
};
AcceptNewMail: PUBLIC ENTRY PROC[activeVersion: INT] = {
ENABLE UNWIND => NULL;
Anm: PROC[inProgress: BOOL] = {
at: INT;
IF ~inProgress THEN {
[] ← WalnutDB.VerifyMsgSet[[WalnutOps.ActiveMsgSetName, activeVersion]];
at ← WalnutLog.AcceptNewMail[].at;
WalnutDB.SetOpInProgressPos[at];
}
ELSE at ← WalnutDB.GetAcceptNewMailPos[];
WalnutDB.AcceptNewMail[at, activeVersion];
};
WalnutOpsInternal.CheckInProgress[];
WalnutOpsInternal.LongRunningApply[Anm];
WalnutOpsInternal.newMailSomewhere ← FALSE;
};
END.