lace.event: Add an event connector to speed up remote connections.
This commit is contained in:
378
1-base/lace/source/events/lace-event_connector.adb
Normal file
378
1-base/lace/source/events/lace-event_connector.adb
Normal file
@@ -0,0 +1,378 @@
|
|||||||
|
with
|
||||||
|
lace.Event.utility,
|
||||||
|
|
||||||
|
ada.Text_IO,
|
||||||
|
ada.Exceptions,
|
||||||
|
ada.unchecked_Deallocation,
|
||||||
|
ada.Containers.Vectors;
|
||||||
|
|
||||||
|
|
||||||
|
package body lace.event_Connector
|
||||||
|
is
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--- Containers.
|
||||||
|
--
|
||||||
|
|
||||||
|
package connector_Vectors is new ada.Containers.Vectors (Positive,
|
||||||
|
Connector_view);
|
||||||
|
subtype connector_Vector is connector_Vectors.Vector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
--- Safe connectors.
|
||||||
|
--
|
||||||
|
|
||||||
|
protected
|
||||||
|
type safe_Connectors
|
||||||
|
is
|
||||||
|
procedure add (new_Connector : in Connector_view);
|
||||||
|
procedure get ( a_Connector : out Connector_view);
|
||||||
|
|
||||||
|
private
|
||||||
|
all_Connectors : connector_Vector;
|
||||||
|
end safe_Connectors;
|
||||||
|
|
||||||
|
type safe_Connectors_view is access all safe_Connectors;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------
|
||||||
|
--- Connector.
|
||||||
|
--
|
||||||
|
|
||||||
|
task
|
||||||
|
type Connector
|
||||||
|
is
|
||||||
|
entry connect (Self : in Connector_view;
|
||||||
|
the_Connection : in Connection;
|
||||||
|
Connectors : in safe_Connectors_view);
|
||||||
|
end Connector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
task body Connector
|
||||||
|
is
|
||||||
|
use ada.Text_IO,
|
||||||
|
lace.Text;
|
||||||
|
|
||||||
|
Myself : Connector_view;
|
||||||
|
my_Connection : Connection;
|
||||||
|
connector_Pool : safe_Connectors_view;
|
||||||
|
begin
|
||||||
|
loop
|
||||||
|
begin
|
||||||
|
select
|
||||||
|
accept connect (Self : in Connector_view;
|
||||||
|
the_Connection : in Connection;
|
||||||
|
Connectors : in safe_Connectors_view)
|
||||||
|
do
|
||||||
|
my_Connection := the_Connection;
|
||||||
|
Myself := Self;
|
||||||
|
connector_Pool := Connectors;
|
||||||
|
end connect;
|
||||||
|
or
|
||||||
|
terminate;
|
||||||
|
end select;
|
||||||
|
|
||||||
|
if my_Connection.is_Connecting
|
||||||
|
then
|
||||||
|
lace.Event.utility.connect (the_Observer => my_Connection.Observer,
|
||||||
|
to_Subject => my_Connection.Subject,
|
||||||
|
with_Response => my_Connection.Response,
|
||||||
|
to_Event_Kind => Event.Kind (+my_Connection.Event_Kind));
|
||||||
|
else
|
||||||
|
lace.Event.utility.disconnect (the_Observer => my_Connection.Observer,
|
||||||
|
from_Subject => my_Connection.Subject,
|
||||||
|
for_Response => my_Connection.Response,
|
||||||
|
to_Event_Kind => Event.Kind (+my_Connection.Event_Kind),
|
||||||
|
subject_Name => my_Connection.Subject.Name);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
connector_Pool.add (Myself); -- Return the connector to the safe pool.
|
||||||
|
|
||||||
|
exception
|
||||||
|
when E : others =>
|
||||||
|
new_Line;
|
||||||
|
put_Line (ada.Exceptions.exception_Information (E));
|
||||||
|
put_Line ("Error detected in 'lace.event_Connector.Connector' task.");
|
||||||
|
new_Line;
|
||||||
|
put_Line ("Subject: '" & my_Connection.Subject.Name & "'.");
|
||||||
|
put_Line ("Observer: '" & my_Connection.Observer.Name & "'.");
|
||||||
|
put_Line ("Event: '" & (+my_Connection.Event_Kind) & "'.");
|
||||||
|
put_Line ("Response '" & my_Connection.Response.Name & "'.");
|
||||||
|
new_Line;
|
||||||
|
put_Line ("Continuing.");
|
||||||
|
new_Line (2);
|
||||||
|
|
||||||
|
connector_Pool.add (Myself); -- Return the connector to the safe pool.
|
||||||
|
end;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
exception
|
||||||
|
when E : others =>
|
||||||
|
new_Line;
|
||||||
|
put_Line (ada.Exceptions.exception_Information (E));
|
||||||
|
put_Line ("Fatal error detected in 'lace.event_Connector.Connector' task.");
|
||||||
|
new_Line;
|
||||||
|
put_Line ("Subject: '" & my_Connection.Subject.Name & "'.");
|
||||||
|
put_Line ("Observer: '" & my_Connection.Observer.Name & "'.");
|
||||||
|
put_Line ("Event: '" & (+my_Connection.Event_Kind) & "'.");
|
||||||
|
put_Line ("Response '" & my_Connection.Response.Name & "'.");
|
||||||
|
new_Line (2);
|
||||||
|
end Connector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
--- Connection delegator.
|
||||||
|
--
|
||||||
|
|
||||||
|
task body connection_Delegator
|
||||||
|
is
|
||||||
|
use ada.Text_IO;
|
||||||
|
|
||||||
|
the_Connectors : aliased safe_Connectors;
|
||||||
|
the_Connections : safe_Connections_view;
|
||||||
|
new_Connections : connection_Vector;
|
||||||
|
Done : Boolean := False;
|
||||||
|
|
||||||
|
|
||||||
|
procedure shutdown
|
||||||
|
is
|
||||||
|
procedure free is new ada.unchecked_Deallocation (Connector,
|
||||||
|
Connector_view);
|
||||||
|
the_Connector : Connector_view;
|
||||||
|
begin
|
||||||
|
loop
|
||||||
|
the_Connectors.get (the_Connector);
|
||||||
|
exit when the_Connector = null;
|
||||||
|
|
||||||
|
free (the_Connector);
|
||||||
|
end loop;
|
||||||
|
end shutdown;
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
ada.text_io.put_Line ("KKK0");
|
||||||
|
|
||||||
|
accept start (Connections : in safe_Connections_view)
|
||||||
|
do
|
||||||
|
ada.text_io.put_Line ("KKK2");
|
||||||
|
|
||||||
|
the_Connections := Connections;
|
||||||
|
ada.text_io.put_Line ("KKK3");
|
||||||
|
|
||||||
|
end start;
|
||||||
|
|
||||||
|
|
||||||
|
loop
|
||||||
|
select
|
||||||
|
accept stop
|
||||||
|
do
|
||||||
|
Done := True;
|
||||||
|
end stop;
|
||||||
|
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
end select;
|
||||||
|
|
||||||
|
|
||||||
|
exit when Done
|
||||||
|
and the_Connections.is_Empty;
|
||||||
|
|
||||||
|
the_Connections.get (new_Connections);
|
||||||
|
|
||||||
|
for each_Connection of new_Connections
|
||||||
|
loop
|
||||||
|
declare
|
||||||
|
use lace.Text;
|
||||||
|
the_Connector : Connector_view;
|
||||||
|
begin
|
||||||
|
the_Connectors.get (the_Connector);
|
||||||
|
|
||||||
|
if the_Connector = null
|
||||||
|
then
|
||||||
|
the_Connector := new Connector;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
the_Connector.connect (Self => the_Connector,
|
||||||
|
the_Connection => each_Connection,
|
||||||
|
Connectors => the_Connectors'unchecked_Access);
|
||||||
|
exception
|
||||||
|
when E : others =>
|
||||||
|
new_Line;
|
||||||
|
put_Line (ada.Exceptions.exception_Information (E));
|
||||||
|
new_Line;
|
||||||
|
put_Line ("Error detected in 'lace.event_Connector.connector_Delegator'.");
|
||||||
|
new_Line;
|
||||||
|
put_Line ("Subject: '" & each_Connection.Subject.Name & "'.");
|
||||||
|
put_Line ("Observer: '" & each_Connection.Observer.Name & "'.");
|
||||||
|
put_Line ("Event: '" & (+each_Connection.Event_Kind) & "'.");
|
||||||
|
put_Line ("Response '" & each_Connection.Response.Name & "'.");
|
||||||
|
new_Line;
|
||||||
|
put_Line ("Continuing.");
|
||||||
|
new_Line (2);
|
||||||
|
end;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
delay 0.001; -- Keep task from churning when idle.
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
shutdown;
|
||||||
|
|
||||||
|
exception
|
||||||
|
when E : others =>
|
||||||
|
new_Line;
|
||||||
|
put_Line (ada.Exceptions.exception_Information (E));
|
||||||
|
new_Line;
|
||||||
|
put_Line ("Fatal error detected in 'lace.event_Connector.connection_Delegator'.");
|
||||||
|
new_Line (2);
|
||||||
|
|
||||||
|
shutdown;
|
||||||
|
end connection_Delegator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
--- Safe connections.
|
||||||
|
--
|
||||||
|
|
||||||
|
protected body safe_Connections
|
||||||
|
is
|
||||||
|
|
||||||
|
procedure add (new_Connection : in Connection)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
all_Connections.append (new_Connection);
|
||||||
|
end add;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure get (the_Connections : out connection_Vector)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
the_Connections := all_Connections;
|
||||||
|
all_Connections.clear;
|
||||||
|
end get;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function is_Empty return Boolean
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
return all_Connections.is_Empty;
|
||||||
|
end is_Empty;
|
||||||
|
|
||||||
|
|
||||||
|
end safe_Connections;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------
|
||||||
|
--- Safe emitters.
|
||||||
|
--
|
||||||
|
|
||||||
|
protected body safe_Connectors
|
||||||
|
is
|
||||||
|
|
||||||
|
procedure add (new_Connector : in Connector_view)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
all_Connectors.append (new_Connector);
|
||||||
|
end add;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure get (a_Connector : out Connector_view)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
if all_Connectors.is_Empty
|
||||||
|
then
|
||||||
|
a_Connector := null;
|
||||||
|
else
|
||||||
|
a_Connector := all_Connectors.last_Element;
|
||||||
|
all_Connectors.delete_Last;
|
||||||
|
end if;
|
||||||
|
end get;
|
||||||
|
|
||||||
|
|
||||||
|
end safe_Connectors;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
--- event_Connector item.
|
||||||
|
--
|
||||||
|
|
||||||
|
procedure define (Self : in out Item)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
ada.text_io.put_Line ("KKK");
|
||||||
|
Self.Delegator.start (Connections => Self.Connections'unchecked_Access);
|
||||||
|
ada.text_io.put_Line ("JJJ");
|
||||||
|
end define;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure destruct (Self : in out Item)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
Self.Delegator.stop;
|
||||||
|
end destruct;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure connect (Self : in out Item; the_Observer : in Observer.view;
|
||||||
|
to_Subject : in Subject .view;
|
||||||
|
with_Response : in Response.view;
|
||||||
|
to_Event_Kind : in Event.Kind)
|
||||||
|
is
|
||||||
|
use lace.Text;
|
||||||
|
|
||||||
|
new_Connection : Connection := (Observer => the_Observer,
|
||||||
|
Subject => to_Subject,
|
||||||
|
Response => with_Response,
|
||||||
|
Event_Kind => <>,
|
||||||
|
subject_Name => <>,
|
||||||
|
is_Connecting => True);
|
||||||
|
begin
|
||||||
|
String_is (new_Connection.Event_Kind,
|
||||||
|
String (to_Event_Kind));
|
||||||
|
|
||||||
|
Self.Connections.add (new_Connection);
|
||||||
|
end connect;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure disconnect (Self : in out Item; the_Observer : in Observer.view;
|
||||||
|
from_Subject : in Subject .view;
|
||||||
|
for_Response : in Response.view;
|
||||||
|
to_Event_Kind : in Event.Kind;
|
||||||
|
subject_Name : in String)
|
||||||
|
is
|
||||||
|
use lace.Text;
|
||||||
|
|
||||||
|
new_Disconnection : Connection := (Observer => the_Observer,
|
||||||
|
Subject => from_Subject,
|
||||||
|
Response => for_Response,
|
||||||
|
Event_Kind => <>,
|
||||||
|
subject_Name => <>,
|
||||||
|
is_Connecting => False);
|
||||||
|
begin
|
||||||
|
String_is (new_Disconnection.event_Kind,
|
||||||
|
String (to_Event_Kind));
|
||||||
|
|
||||||
|
String_is (new_Disconnection.subject_Name,
|
||||||
|
subject_Name);
|
||||||
|
|
||||||
|
Self.Connections.add (new_Disconnection);
|
||||||
|
end disconnect;
|
||||||
|
|
||||||
|
|
||||||
|
end lace.event_Connector;
|
||||||
116
1-base/lace/source/events/lace-event_connector.ads
Normal file
116
1-base/lace/source/events/lace-event_connector.ads
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
with
|
||||||
|
lace.Event,
|
||||||
|
lace.Response,
|
||||||
|
lace.Observer,
|
||||||
|
lace.Subject;
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
with
|
||||||
|
lace.Text,
|
||||||
|
ada.Containers.indefinite_Vectors;
|
||||||
|
|
||||||
|
|
||||||
|
package lace.event_Connector
|
||||||
|
is
|
||||||
|
|
||||||
|
type Item is tagged limited private;
|
||||||
|
|
||||||
|
|
||||||
|
procedure define (Self : in out Item);
|
||||||
|
procedure destruct (Self : in out Item);
|
||||||
|
|
||||||
|
procedure connect (Self : in out Item; the_Observer : in Observer.view;
|
||||||
|
to_Subject : in Subject .view;
|
||||||
|
with_Response : in Response.view;
|
||||||
|
to_Event_Kind : in Event.Kind);
|
||||||
|
|
||||||
|
procedure disconnect (Self : in out Item; the_Observer : in Observer.view;
|
||||||
|
from_Subject : in Subject .view;
|
||||||
|
for_Response : in Response.view;
|
||||||
|
to_Event_Kind : in Event.Kind;
|
||||||
|
subject_Name : in String);
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
--------------
|
||||||
|
--- Connector.
|
||||||
|
--
|
||||||
|
|
||||||
|
type Connector;
|
||||||
|
type Connector_view is access Connector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--- Connection.
|
||||||
|
--
|
||||||
|
|
||||||
|
type Connection is
|
||||||
|
record
|
||||||
|
Observer : lace.Observer.view;
|
||||||
|
Subject : lace.Subject .view;
|
||||||
|
Response : lace.Response.view;
|
||||||
|
Event_Kind : lace.Text.item_256;
|
||||||
|
subject_Name : lace.Text.item_256;
|
||||||
|
is_Connecting : Boolean;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--- Containers.
|
||||||
|
--
|
||||||
|
|
||||||
|
package connection_Vectors is new ada.Containers.indefinite_Vectors (Positive,
|
||||||
|
Connection);
|
||||||
|
subtype connection_Vector is connection_Vectors.Vector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
--- Safe connections.
|
||||||
|
--
|
||||||
|
|
||||||
|
protected
|
||||||
|
type safe_Connections
|
||||||
|
is
|
||||||
|
procedure add (new_Connection : in Connection);
|
||||||
|
procedure get (the_Connections : out connection_Vector);
|
||||||
|
|
||||||
|
function is_Empty return Boolean;
|
||||||
|
|
||||||
|
private
|
||||||
|
all_Connections : connection_Vector;
|
||||||
|
end safe_Connections;
|
||||||
|
|
||||||
|
type safe_Connections_view is access all safe_Connections;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
--- Connection delegator.
|
||||||
|
--
|
||||||
|
|
||||||
|
task
|
||||||
|
type connection_Delegator
|
||||||
|
is
|
||||||
|
entry start (Connections : in safe_Connections_view);
|
||||||
|
entry stop;
|
||||||
|
end connection_Delegator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------
|
||||||
|
--- Item.
|
||||||
|
--
|
||||||
|
|
||||||
|
type Item is tagged limited
|
||||||
|
record
|
||||||
|
Connections : aliased safe_Connections;
|
||||||
|
Delegator : connection_Delegator;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
|
||||||
|
end lace.event_Connector;
|
||||||
@@ -62,6 +62,7 @@ is
|
|||||||
end connect;
|
end connect;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
procedure disconnect (the_Observer : in Observer.view;
|
procedure disconnect (the_Observer : in Observer.view;
|
||||||
from_Subject : in Subject .view;
|
from_Subject : in Subject .view;
|
||||||
for_Response : in Response.view;
|
for_Response : in Response.view;
|
||||||
|
|||||||
Reference in New Issue
Block a user