11create or replace package body ut_output_pipe_helper is
22
33
4- type t_pipe_buffer is table of varchar2(4000);
5- type t_outputs_buffer is table of t_pipe_buffer index by varchar2(128);
4+ type tt_pipe_buffer is table of varchar2(4000);
65
7- g_outputs_buffer t_outputs_buffer;
6+ type t_output_buffer is record(
7+ to_close boolean := false,
8+ data tt_pipe_buffer
9+ );
810
9- procedure send_from_buffer(a_output_id varchar2) is
10- l_timeout_occured boolean;
11+ type tt_outputs_buffer is table of t_output_buffer index by varchar2(128);
12+
13+ g_outputs_buffer tt_outputs_buffer;
14+
15+ function send_from_buffer(a_output_id varchar2, a_buffer in out nocopy tt_pipe_buffer) return boolean is
16+ l_is_successful boolean := true;
17+ l_first_item integer;
18+ l_last_item integer;
1119 i integer;
1220 begin
13- if g_outputs_buffer.exists(a_output_id) then
14- i := g_outputs_buffer(a_output_id).first;
21+ if a_buffer is not null then
22+ l_first_item := a_buffer.first;
23+ i := l_first_item;
24+ --iterate through buffer and try to sent all data from buffer
25+ -- exit loop on timeout
1526 while i is not null loop
16- dbms_pipe.pack_message( g_outputs_buffer(a_output_id)(i) );
17- l_timeout_occured := dbms_pipe.send_message(a_output_id, 0) != 0;
18- if l_timeout_occured then
19- dbms_pipe.reset_buffer;
20- return;
21- end if;
27+ dbms_pipe.pack_message( a_buffer(i) );
28+ l_is_successful := dbms_pipe.send_message(a_output_id, 0) = 0;
29+ exit when not l_is_successful;
30+ l_last_item := i;
31+ i := a_buffer.next(i);
2232 end loop;
33+
34+ --remove from buffer messages alrady sent
35+ if not l_is_successful then
36+ a_buffer.delete(l_first_item, i-1);
37+ else
38+ a_buffer.delete();
39+ end if;
40+ dbms_pipe.reset_buffer;
41+ return l_is_successful;
42+ end if;
43+ return false;
44+ end;
45+
46+ function send_from_buffer(a_output_id varchar2) return boolean is
47+ begin
48+ if g_outputs_buffer.exists(a_output_id) then
49+ return send_from_buffer(a_output_id, g_outputs_buffer(a_output_id).data);
2350 end if;
51+ return false;
2452 end;
2553
2654 --sends a message to a named pipe
2755 --and if sending fails it writes the message to the end of the buffer for pipe
28- procedure send(a_output_id varchar2, a_text varchar2 ) is
29- l_timeout_occured boolean;
56+ procedure send(a_output_id varchar2, a_text t_pipe_item ) is
57+ l_is_successful boolean;
3058 begin
31- send_from_buffer(a_output_id);
32- dbms_pipe.pack_message( a_text );
33- l_timeout_occured := dbms_pipe.send_message(a_output_id, 0) != 0;
34- if l_timeout_occured then
35- dbms_pipe.reset_buffer;
36- buffer(a_output_id, a_text);
37- end if;
59+ buffer(a_output_id, a_text);
60+ l_is_successful := send_from_buffer(a_output_id);
3861 end;
3962
4063 --writes the message to the end of the buffer for pipe
41- procedure buffer(a_output_id varchar2, a_text varchar2 ) is
64+ procedure buffer(a_output_id varchar2, a_text t_pipe_item ) is
4265 begin
4366 if not g_outputs_buffer.exists(a_output_id) then
44- g_outputs_buffer(a_output_id) := t_pipe_buffer ();
67+ g_outputs_buffer(a_output_id).data := tt_pipe_buffer ();
4568 end if;
46- g_outputs_buffer(a_output_id).extend;
47- g_outputs_buffer(a_output_id)(g_outputs_buffer(a_output_id).last) := a_text;
69+ g_outputs_buffer(a_output_id).data.extend;
70+ g_outputs_buffer(a_output_id).data(g_outputs_buffer(a_output_id).data.last) := a_text;
71+ end;
72+
73+ procedure cleanup_outputs_to_close is
74+ l_output_id varchar2(128);
75+ l_output_id_to_delete varchar2(128);
76+ begin
77+ l_output_id := g_outputs_buffer.first;
78+ while i is not null loop
79+ l_output_id_to_delete := null;
80+ if g_outputs_buffer(l_output_id).to_close then
81+ if send_from_buffer(l_output_id) = true then
82+ l_output_id_to_delete := l_output_id;
83+ end if;
84+ end if;
85+ l_output_id := g_outputs_buffer.next(l_output_id);
86+ g_outputs_buffer.delete(l_output_id_to_delete);
87+ end loop;
4888 end;
4989
90+ --procedure cleanup_aged_pipes() - check for pipes that are aged out.
91+
92+
5093 --registers a close request and tries to close a pipe
5194 --by first sending out all messages remaining in the buffers
5295 --the procedure holds infomrmation about closure requests
@@ -73,7 +116,13 @@ create or replace package body ut_output_pipe_helper is
73116 -- two buffers used: output_1, output_2
74117 procedure request_close(a_output_id varchar2, a_text varchar2) is
75118 begin
76- null;
119+ cleanup_outputs_to_close;
120+ --if there is any output in a state to_close = false
121+ --exit
122+ --else loop with a wait time of 20 seconds for each to_close output
123+
124+ --if unable to send all messages after timeout, then finish?
125+
77126 end;
78127
79128end;
0 commit comments