summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Event/EC_Gateway.h
blob: 46a1ca2233e47e67416a20e115426bf27408e49d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* -*- C++ -*- */
// $Id$
//
// ============================================================================
//
// = LIBRARY
//   TAO services
//
// = FILENAME
//   EC_Gateway
//
// = AUTHOR
//   Carlos O'Ryan
//
// = DESCRIPTION
//   This class can be used to connect two event channels; the class
//   connects to a "remote" EC as a consumer, it also connects to the
//   <local> EC as a supplier of events, this later EC is usually
//   collocated.
//   The QoS parameters for both connections must be provided by the
//   user.
//   To avoid infinite loops of events the Gateway descreases the TTL
//   field of the events and will not deliver any events with TTL less
//   than or equal to 0.
//
// = TODO
//   The class makes an extra copy of the events, we need to
//   investigate if closer collaboration with its collocated EC could
//   be used to remove that copy.
//
// ============================================================================

#ifndef TAO_EC_GATEWAY_H
#define TAO_EC_GATEWAY_H

#include "orbsvcs/RtecEventChannelAdminS.h"
#include "orbsvcs/RtecEventCommS.h"
#include "orbsvcs/Channel_Clients_T.h"
#include "orbsvcs/orbsvcs_export.h"

class TAO_ORBSVCS_Export TAO_EC_Gateway : public POA_RtecEventChannelAdmin::Observer
{
  // = TITLE
  //   Event Channel Gateway
  //
  // = DESCRIPTION
  //   There are several ways to connect several EC together, for
  //   instance:
  //   + A single class can use normal IIOP and connect to one EC as
  //     a supplier and to another EC as a consumer.
  //   + A class connects as a consumer and transmit the events using
  //     multicast, another class receives the multicast messages and
  //     transform them back into a push() call.
  //
  //   This is an abstract class to represent all the different
  //   strategies for EC distribution.
  //
public:
  TAO_EC_Gateway (void);
  // Default constructor.

  virtual ~TAO_EC_Gateway (void);
  // Destructor

  virtual void close (CORBA::Environment& env) = 0;
  // The gateway must disconnect from all the relevant event channels,
  // or any other communication media (such as multicast groups).

private:
  friend class ACE_EventChannel;
  void observer_handle (RtecEventChannelAdmin::Observer_Handle h);
  RtecEventChannelAdmin::Observer_Handle observer_handle (void) const;
  // Obtain and modify the observer handle.

private:
  RtecEventChannelAdmin::Observer_Handle handle_;
};

// ****************************************************************
class TAO_ORBSVCS_Export TAO_EC_Gateway_IIOP : public TAO_EC_Gateway
//
// = TITLE
//   Event Channel Gateway using IIOP.
//
// = DESCRIPTION
//   This class mediates among two event channels, it connects as a
//   consumer of events with a remote event channel, and as a supplier
//   of events with the local EC.
//   As a consumer it gives a QoS designed to only accept the events
//   in which *local* consumers are interested.
//   Eventually the local EC should create this object and compute its
//   QoS in an automated manner; but this requires some way to filter
//   out the peers registered as consumers, otherwise we will get
//   loops in the QoS graph.
//   It uses exactly the same set of events in the publications list
//   when connected as a supplier.
//
// = NOTES
//   An alternative implementation would be to register with the
//   remote EC as a supplier, and then filter on the remote EC, but
//   one of the objectives is to minimize network traffic.
//   On the other hand the events will be pushed to remote consumers,
//   event though they will be dropped upon receipt (due to the TTL
//   field); IMHO this is another suggestion that the EC needs to know
//   (somehow) which consumers are truly its peers in disguise.
//
//
{
public:
  TAO_EC_Gateway_IIOP (void);
  ~TAO_EC_Gateway_IIOP (void);

  void init (RtecEventChannelAdmin::EventChannel_ptr rmt_ec,
             RtecEventChannelAdmin::EventChannel_ptr lcl_ec,
             RtecScheduler::Scheduler_ptr rmt_sched,
             RtecScheduler::Scheduler_ptr lcl_sched,
             const char* lcl_name,
             const char* rmt_name,
             CORBA::Environment &_env);
  // To do its job this class requires to know the local and remote
  // ECs it will connect to; furthermore it also requires to build
  // RT_Infos for the local and remote schedulers.
  // @@ TODO part of the RT_Info is hardcoded, we need to make it
  // parametric.

  void disconnect_push_supplier (CORBA::Environment &);
  // The channel is disconnecting.

  void disconnect_push_consumer (CORBA::Environment &);
  // The channel is disconnecting.

  void push (const RtecEventComm::EventSet &events,
             CORBA::Environment &);
  // This is the Consumer side behavior, it pushes the events to the
  // local event channel.

  int shutdown (CORBA::Environment&);
  // Disconnect and shutdown the gateway

  // The following methods are documented in the base class.
  virtual void close (CORBA::Environment& _env);
  virtual void update_consumer (const RtecEventChannelAdmin::ConsumerQOS& sub,
                                CORBA::Environment& env);
  virtual void update_supplier (const RtecEventChannelAdmin::SupplierQOS& pub,
                                CORBA::Environment& env);

private:
  RtecEventChannelAdmin::EventChannel_var rmt_ec_;
  RtecEventChannelAdmin::EventChannel_var lcl_ec_;
  // The remote and the local EC, so we can reconnect when the list changes.

  RtecScheduler::handle_t rmt_info_;
  RtecScheduler::handle_t lcl_info_;
  // Our local and remote RT_Infos.

  ACE_PushConsumer_Adapter<TAO_EC_Gateway_IIOP> consumer_;
  // Our consumer personality....

  ACE_PushSupplier_Adapter<TAO_EC_Gateway_IIOP> supplier_;
  // Our supplier personality....

  // We use a different Consumer_Proxy 
  typedef ACE_Map_Manager<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex> Consumer_Map;
  typedef ACE_Map_Iterator<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex> Consumer_Map_Iterator;
  
  Consumer_Map consumer_proxy_map_;
  RtecEventChannelAdmin::ProxyPushConsumer_var default_consumer_proxy_;
  // We talk to the EC (as a supplier) using either an per-supplier
  // proxy or a generic proxy for the type only subscriptions.

  RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_;
  // We talk to the EC (as a consumer) using this proxy.
};

#endif /* ACE_EC_GATEWAY_H */