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.