|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: B T
Length: 15542 (0x3cb6)
Types: TextFile
Names: »B«
└─⟦180fe333a⟧ Bits:30000405 8mm tape, Rational 1000, SW CATALOG, 10_20_0
└─⟦180fe333a⟧ Bits:30000537 8mm tape, Rational 1000, SW Catalog 10_20_0
└─⟦5cb1d1d7f⟧ »DATA«
└─⟦3b1ee7bd8⟧
└─⟦this⟧
with Message;
with Directory_Tools;
with String_Utilities;
with Profile;
with Log;
with Batch_Commands;
with Batch_Stream;
with Time_Utilities;
with Program;
with Operator;
with System_Utilities;
with Simple_Status;
package body Batch_Server is
subtype Number is Natural range 0 .. Number_Of_Streams;
task Command_Reader is
entry Start;
end Command_Reader;
task type Stream is
entry Initialize (Stream_Number : Number);
entry Kill;
entry Refresh;
end Stream;
type Stream_Array is array (1 .. Number_Of_Streams) of Stream;
Streams : Stream_Array;
task body Command_Reader is
The_Channel : Batch_Commands.Channel;
The_Command : Batch_Commands.Command;
The_Job : Batch_Stream.Job_Descriptor;
Ok : Boolean := False;
begin
accept Start do
Batch_Commands.Open_Read_Channel (The_Channel);
loop
The_Command := Batch_Commands.Get (The_Channel);
The_Job := Batch_Commands.Job_Description (The_Command);
case Batch_Commands.The_Instruction (The_Command) is
when Batch_Commands.Submit =>
begin
Batch_Stream.Add_To_Stream
(Stream_Number =>
Batch_Commands.Stream_Number (The_Command),
The_Job => The_Job);
select
Streams (Batch_Commands.Stream_Number
(The_Command)).Refresh;
else
null;
end select;
exception
when Batch_Stream.Queue_Is_Full =>
Log.Put_Line
("Queue is full - could not submit " &
Batch_Stream.Command (The_Job),
Profile.Error_Msg);
when Batch_Stream.File_Access_Error =>
Log.Put_Line
("Could not access file for stream" &
Natural'Image (Batch_Commands.Stream_Number
(The_Command)) &
" to submit a job", Profile.Error_Msg);
end;
when Batch_Commands.Cancel =>
begin
Batch_Stream.Change_State
(Of_Job_Number => Batch_Stream.Number (The_Job),
To => Batch_Stream.Cancelled,
In_Stream => Batch_Commands.Stream_Number
(The_Command),
Successful => Ok);
if Ok then
select
Streams (Batch_Commands.Stream_Number
(The_Command)).Refresh;
else
null;
end select;
else
Log.Put_Line
("Could not cancel queue job number" &
Batch_Stream.Job_Identifier'Image
(Batch_Stream.Number (The_Job)),
Profile.Warning_Msg);
end if;
exception
when Batch_Stream.File_Access_Error =>
Log.Put_Line
("Could not access file for stream" &
Natural'Image (Batch_Commands.Stream_Number
(The_Command)) &
" to cancel a job", Profile.Error_Msg);
end;
when Batch_Commands.Shutdown =>
if Batch_Commands.Stream_Number (The_Command) = 0 then
for I in 1 .. Number_Of_Streams loop
Streams (I).Kill;
end loop;
exit;
else
Streams
(Batch_Commands.Stream_Number (The_Command)).
Kill;
end if;
end case;
end loop;
end Start;
end Command_Reader;
task body Stream is
My_Number : Number;
Next_Job : Batch_Stream.Job_Descriptor := Batch_Stream.Nil;
Scheduled_Job : Batch_Stream.Job_Descriptor := Batch_Stream.Nil;
Found_One : Boolean := False;
Delay_Time : Duration := Duration'Last;
Ok : Boolean := False;
R1000_Job : Program.Job_Id;
R1000_Status : Program.Condition;
function Option_String
(For_Job : Batch_Stream.Job_Descriptor) return String is
Job_Name : constant String := "Name=>Queue Id#";
Job_Num : constant String := Batch_Stream.Job_Identifier'Image
(Batch_Stream.Number (For_Job));
Error_Label : constant String := ",error=>";
Error_Value : constant String :=
Batch_Stream.Error_Filename (For_Job);
Input_Label : constant String := ",input=>";
Input_Value : constant String :=
Batch_Stream.Input_Filename (For_Job);
Output_Label : constant String := ",output=>";
Output_Value : constant String :=
Batch_Stream.Output_Filename (For_Job);
function Component_String
(Label : String; Value : String) return String is
begin
if Value = "" then
return "";
else
return Label & Value;
end if;
end Component_String;
begin
return Job_Name & Job_Num & Component_String
(Input_Label, Input_Value) &
Component_String (Error_Label, Error_Value) &
Component_String (Output_Label, Output_Value);
end Option_String;
begin
accept Initialize (Stream_Number : Number) do
declare
use Batch_Stream;
The_Iter : Batch_Stream.Iterator;
The_Job : Batch_Stream.Job_Descriptor;
Ok : Boolean;
begin
My_Number := Stream_Number;
Batch_Stream.Initialize (My_Number, The_Iter);
Batch_Stream.Delete_Stream (My_Number);
Batch_Stream.Initialize_Stream (My_Number);
while not Batch_Stream.Done (The_Iter) loop
The_Job := Batch_Stream.Value (The_Iter);
if Batch_Stream.State (The_Job) = Batch_Stream.Running or
Batch_Stream.State (The_Job) = Batch_Stream.Waiting then
if Batch_Stream.Restartable (The_Job) then
Batch_Stream.Add_To_Stream
(Stream_Number => My_Number, The_Job => The_Job);
end if;
end if;
Batch_Stream.Next (The_Iter);
end loop;
exception
when Batch_Stream.File_Access_Error =>
Batch_Stream.Delete_Stream (My_Number);
Batch_Stream.Initialize_Stream (My_Number);
end;
end Initialize;
loop
select
accept Kill do
Batch_Stream.Delete_Stream (Stream_Number => My_Number);
abort Streams (My_Number);
end Kill;
or
accept Refresh do
Batch_Stream.Get_Next_Job_To_Run (From_Stream => My_Number,
The_Job => Next_Job,
Found_One => Found_One);
if Found_One then
Scheduled_Job := Next_Job;
Delay_Time := Time_Utilities.Duration_Until
(Batch_Stream.Start_Time
(Scheduled_Job));
else
Scheduled_Job := Batch_Stream.Nil;
Delay_Time := Duration'Last;
end if;
end Refresh;
or
delay Delay_Time;
Batch_Stream.Change_State
(Of_Job_Number => Batch_Stream.Number (Scheduled_Job),
To => Batch_Stream.Running,
In_Stream => My_Number,
Successful => Ok);
if Ok then
declare
The_Option_String : constant String :=
Option_String (Scheduled_Job);
begin
Program.Change_Identity
(To_User => Batch_Stream.Username (Scheduled_Job),
Password => "",
Options => "",
Status => R1000_Status);
if Simple_Status.Error (R1000_Status) then
Log.Put_Line ("Error changing user id - " &
Simple_Status.Display_Message
(R1000_Status), Profile.Error_Msg);
Message.Send (Batch_Stream.Username (Scheduled_Job),
"ERROR - Could not run job as " &
Batch_Stream.Username
(Scheduled_Job));
else
Program.Create_Job
(S => Batch_Stream.Command (Scheduled_Job),
Job => R1000_Job,
Status => R1000_Status,
Debug => False,
Context => Batch_Stream.Context (Scheduled_Job),
After => 0.0,
Options => The_Option_String,
Response => Batch_Stream.Response
(Scheduled_Job));
if Simple_Status.Error (R1000_Status) then
Log.Put_Line ("Error running job - " &
Simple_Status.Display_Message
(R1000_Status),
Profile.Error_Msg);
Message.Send
(Batch_Stream.Username (Scheduled_Job),
"ERROR - Problem running batch job " &
Simple_Status.Display_Message
(R1000_Status));
end if;
Program.Wait_For (Job => R1000_Job);
Log.Put_Line ("Queue Id#" &
Natural'Image (Batch_Stream.Number
(Scheduled_Job)) &
" submitted by " &
Batch_Stream.Username
(Scheduled_Job) & " - " &
Batch_Stream.Command
(Scheduled_Job), Profile.Note_Msg);
Log.Put_Line ("Queue Id #" &
Natural'Image (Batch_Stream.Number
(Scheduled_Job)) &
" completed", Profile.Positive_Msg);
end if;
end;
Program.Change_Identity
(To_User => "",
Password => "",
Options => "restore_identity,privileged=>true",
Status => R1000_Status);
if Simple_Status.Error (R1000_Status) then
Log.Put_Line ("Error restoring user id - " &
Simple_Status.Display_Message
(R1000_Status), Profile.Error_Msg);
end if;
Message.Send (Batch_Stream.Username (Scheduled_Job),
Batch_Stream.Command (Scheduled_Job) &
" has completed");
end if;
Batch_Stream.Change_State
(Of_Job_Number => Batch_Stream.Number (Scheduled_Job),
To => Batch_Stream.Done,
In_Stream => My_Number,
Successful => Ok);
Batch_Stream.Get_Next_Job_To_Run (From_Stream => My_Number,
The_Job => Next_Job,
Found_One => Found_One);
if Found_One then
Scheduled_Job := Next_Job;
Delay_Time := Time_Utilities.Duration_Until
(Batch_Stream.Start_Time (Scheduled_Job));
else
Scheduled_Job := Batch_Stream.Nil;
Delay_Time := Duration'Last;
end if;
end select;
end loop;
end Stream;
procedure Serve is
procedure Delete_Unused_Stream (Stream_Number : Natural) is
begin
if Stream_Number > Number_Of_Streams then
Batch_Stream.Delete_Stream (Stream_Number);
end if;
end Delete_Unused_Stream;
procedure Delete_All_Unused_Streams is
new Batch_Stream.Traverse_Streams (Delete_Unused_Stream);
begin
Log.Set_Output ("!machine.error_logs.batch_server_log");
Operator.Enable_Privileges;
if not Operator.Privileged_Mode then
Log.Put_Line ("Batch queue not started - insufficient privilege",
Profile.Error_Msg);
for I in 1 .. Number_Of_Streams loop
abort Streams (I);
end loop;
abort Command_Reader;
Message.Send (System_Utilities.User_Name,
"Batch queue not started - insufficient privilege");
else
for I in 1 .. Number_Of_Streams loop
Streams (I).Initialize (I);
Streams (I).Refresh;
end loop;
Batch_Commands.Initialize;
Delete_All_Unused_Streams;
Command_Reader.Start;
end if;
end Serve;
end Batch_Server;