DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: B T

⟦70bd02cc4⟧ TextFile

    Length: 15542 (0x3cb6)
    Types: TextFile
    Names: »B«

Derivation

└─⟦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⟧ 

TextFile

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;