BDE 4.14.0 Production release
Loading...
Searching...
No Matches
ball_multiplexobserver.h
Go to the documentation of this file.
1/// @file ball_multiplexobserver.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_multiplexobserver.h -*-C++-*-
8#ifndef INCLUDED_BALL_MULTIPLEXOBSERVER
9#define INCLUDED_BALL_MULTIPLEXOBSERVER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup ball_multiplexobserver ball_multiplexobserver
15/// @brief Provide a multiplexing observer that forwards to other observers.
16/// @addtogroup bal
17/// @{
18/// @addtogroup ball
19/// @{
20/// @addtogroup ball_multiplexobserver
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#ball_multiplexobserver-purpose"> Purpose</a>
25/// * <a href="#ball_multiplexobserver-classes"> Classes </a>
26/// * <a href="#ball_multiplexobserver-description"> Description </a>
27/// * <a href="#ball_multiplexobserver-thread-safety"> Thread Safety </a>
28/// * <a href="#ball_multiplexobserver-usage"> Usage </a>
29/// * <a href="#ball_multiplexobserver-example-basic-usage"> Example: Basic Usage </a>
30///
31/// # Purpose {#ball_multiplexobserver-purpose}
32/// Provide a multiplexing observer that forwards to other observers.
33///
34/// @deprecated Use @ref ball_broadcastobserver instead.
35///
36/// # Classes {#ball_multiplexobserver-classes}
37///
38/// - ball::MultiplexObserver: multiplexing observer that forwards log records
39///
40/// @see ball_record, ball_context, ball_streamobserver, ball_loggermanager
41///
42/// # Description {#ball_multiplexobserver-description}
43/// This component provides a concrete implementation of the
44/// `ball::Observer` protocol for receiving and processing log records:
45/// @code
46/// ( ball::MultiplexObserver )
47/// | ctor
48/// | registerObserver
49/// | deregisterObserver
50/// | numRegisteredObservers
51/// V
52/// ( ball::Observer )
53/// dtor
54/// publish
55/// releaseRecords
56/// @endcode
57/// `ball::MultiplexObserver` is a concrete class derived from `ball::Observer`
58/// that processes the log records it receives through its `publish` method by
59/// forwarding them to other concrete observers. `ball::MultiplexObserver`
60/// maintains a registry of observers to which it forwards log records. Clients
61/// of `ball::MultiplexObserver` register observers using the `registerObserver`
62/// method and unregister observers with the `deregisterObserver` method. Once
63/// registered, an observer receives all log records that its associated
64/// multiplexing observer receives.
65///
66/// ## Thread Safety {#ball_multiplexobserver-thread-safety}
67///
68///
69/// `ball::MultiplexObserver` is thread-safe and thread-enabled, meaning that
70/// multiple threads may share the same instance, or may have their own
71/// instances.
72///
73/// ## Usage {#ball_multiplexobserver-usage}
74///
75///
76/// This section illustrates intended use of this component.
77///
78/// ### Example: Basic Usage {#ball_multiplexobserver-example-basic-usage}
79///
80///
81/// Note: This usage example retained here for reference purposes for legacy
82/// code that still uses multiplex observers. The use of this component is
83/// strongly discouraged.
84///
85/// Multiplexing observers are used to interface a `ball` logging system, which
86/// generates log records, with the multiplicity of observers that are to
87/// receive the generated records that are published. Establishing this
88/// interface proceeds in three logical steps:
89/// @code
90/// (1) Create a distinguished `ball::MultiplexObserver` that will be the
91/// unique observer to receive log records directly from the logging
92/// system.
93/// (2) Create the other observers required by the application and register
94/// each of these observers with some `ball::MultiplexObserver`. (Note
95/// that a `ball::MultiplexObserver` may be registered with another
96/// `ball::MultiplexObserver`.)
97/// (3) Install the distinguished multiplexor from step (1) within the
98/// `ball` logging system.
99/// @endcode
100/// This example demonstrates the use of a multiplexing observer to forward log
101/// records from a `ball` logging system to three registered observers. Each of
102/// the three registered observers performs distinct actions upon receipt of log
103/// records:
104/// @code
105/// (1) `defaultObserver`, an instance of `ball::StreamObserver`, formats
106/// the records it receives and outputs them to `stdout`.
107/// (2) `logfileObserver`, an instance of `my_LogfileObserver` (assumed to
108/// be a concrete class derived from `ball::Observer`) writes selected
109/// records to a log file.
110/// (3) `encryptingObserver`, an instance of `my_EncryptingObserver` (also
111/// assumed to be a concrete class derived from `ball::Observer`) creates
112/// a compact, encrypted representation of each record, suitable for
113/// sending over an unsecure network.
114/// @endcode
115/// First, we create the three downstream observers that will be registered with
116/// multiplexor observer:
117/// @code
118/// ball::StreamObserver defaultObserver(&bsl::cout);
119/// my_LogfileObserver logfileObserver(&bsl::cout);
120/// my_EncryptingObserver encryptingObserver(&bsl::cout);
121/// @endcode
122/// Next, we create an initially empty multiplexing observer `multiplexor` and
123/// register the three downstream observers `multiplexor`:
124/// @code
125/// ball::MultiplexObserver multiplexor;
126/// assert(0 == multiplexor.numRegisteredObservers());
127///
128/// multiplexor.registerObserver(&defaultObserver);
129/// multiplexor.registerObserver(&logfileObserver);
130/// multiplexor.registerObserver(&encryptingObserver);
131/// assert(3 == multiplexor.numRegisteredObservers());
132/// @endcode
133/// Then, `multiplexor` is installed within a `ball` logging system to be the
134/// direct recipient of published log records. The code uses deprecated
135/// `ball::LoggerManager` API and is elided.
136///
137/// Henceforth, all log records that are published by the logging system will be
138/// transmitted to the `publish` method of `multiplexor` which, in turn,
139/// forwards them to `defaultObserver`, `logfileObserver`, and
140/// `encryptingObserver` by calling their respective `publish` methods.
141///
142/// Finally, deregister the three observers when the logs have been all
143/// forwarded:
144/// @code
145/// multiplexor.deregisterObserver(&defaultObserver);
146/// multiplexor.deregisterObserver(&logfileObserver);
147/// multiplexor.deregisterObserver(&encryptingObserver);
148/// @endcode
149/// Note that any observer must exist before registering with multiplexor. Any
150/// observer already registered must deregister before its destruction.
151/// Additional observers may be registered with `multiplexor` at any time.
152/// Similarly, observers may be unregistered at any time. This capability
153/// allows for extremely flexible observation scenarios.
154/// @}
155/** @} */
156/** @} */
157
158/** @addtogroup bal
159 * @{
160 */
161/** @addtogroup ball
162 * @{
163 */
164/** @addtogroup ball_multiplexobserver
165 * @{
166 */
167
168#include <balscm_version.h>
169
170#include <ball_observer.h>
171
172#include <bslma_allocator.h>
173
174#include <bslmt_readlockguard.h>
175#include <bslmt_rwmutex.h>
176#include <bslmt_writelockguard.h>
177
178#include <bsls_keyword.h>
179
180#include <bsl_memory.h>
181#include <bsl_set.h>
182#include <bsl_vector.h>
183
184
185namespace ball {
186
187class Record;
188class Context;
189
190 // =======================
191 // class MultiplexObserver
192 // =======================
193
194/// This class provides a multiplexing implementation of the `Observer`
195/// protocol. Other concrete observers may be registered with a
196/// multiplexing observer (`registerObserver` method) and later unregistered
197/// (`deregisterObserver` method). The `publish` method of this class
198/// forwards the log records that it receives to the `publish` method of
199/// each registered observer.
200///
201/// See @ref ball_multiplexobserver
203
204 // DATA
205 bsl::set<Observer *> d_observerSet; // observer registry
206
207 mutable bslmt::RWMutex d_rwMutex; // protects concurrent access to
208 // 'd_observerSet'
209
210 // NOT IMPLEMENTED
212 MultiplexObserver& operator=(const MultiplexObserver&);
213
214 public:
215 // CREATORS
216
217 /// Create a multiplexing observer having no registered observers.
218 /// Optionally specify a `basicAllocator` used to supply memory. If
219 /// `basicAllocator` is 0, the currently installed default allocator is
220 /// used.
221 explicit MultiplexObserver(bslma::Allocator *basicAllocator = 0);
222
223 /// Destroy this multiplexing observer. Note that this method has no
224 /// effect on the lifetime of observers registered with this observer, if
225 /// any.
227
228 // MANIPULATORS
229
230 /// Process the specified log `record` having the specified publishing
231 /// `context` by forwarding `record` and `context` to each of the
232 /// observers registered with this multiplexing observer.
233 ///
234 /// @deprecated Use the alternative `publish` overload instead.
235 void publish(const Record& record,
236 const Context& context) BSLS_KEYWORD_OVERRIDE;
237
238 /// Process the specified log `record` having the specified publishing
239 /// `context`. This concrete publish implementations processes the
240 /// `record` by forwarding `record` and `context` to each of the
241 /// observers registered with this multiplexing observer.
242 void publish(const bsl::shared_ptr<const Record>& record,
243 const Context& context)
245
246 /// Discard any shared reference to a `Record` object that was supplied
247 /// to the `publish` method, and is held by this observer. This
248 /// implementation processes `releaseRecords` by calling
249 /// `releaseRecords` on each of the registered observers. Note that
250 /// this operation should be called if resources underlying the
251 /// previously provided shared pointers must be released.
253
254 /// Add the specified `observer` to the registry of this multiplexing
255 /// observer. Return 0 if `observer` is non-null and was not already
256 /// registered with this multiplexing observer, and a non-zero value
257 /// (with no effect) otherwise. Henceforth, this multiplexing observer
258 /// will forward each record it receives through its `publish` method,
259 /// including the record's context, to the `publish` method of
260 /// `observer`, until `observer` is deregistered. The behavior is
261 /// undefined unless `observer` remains valid until it is deregistered
262 /// from this multiplexing observer or until this observer is destroyed.
264
265 /// Remove the specified `observer` from the registry of this
266 /// multiplexing observer. Return 0 if `observer` is non-null and was
267 /// registered with this multiplexing observer, and a non-zero value
268 /// (with no effect) otherwise. Henceforth, `observer` will no longer
269 /// receive log records from this multiplexing observer.
271
272 // ACCESSORS
273
274 /// Return the number of observers registered with this multiplexing
275 /// observer.
276 int numRegisteredObservers() const;
277};
278
279// ============================================================================
280// INLINE DEFINITIONS
281// ============================================================================
282
283 // -----------------------
284 // class MultiplexObserver
285 // -----------------------
286
287// CREATORS
288inline
289MultiplexObserver::MultiplexObserver(bslma::Allocator *basicAllocator)
290: d_observerSet(basicAllocator)
291{
292}
293
294// ACCESSORS
295inline
297{
298 bslmt::ReadLockGuard<bslmt::RWMutex> guard(&d_rwMutex);
299 return static_cast<int>(d_observerSet.size());
300}
301
302} // close package namespace
303
304
305#endif
306
307// ----------------------------------------------------------------------------
308// Copyright 2015 Bloomberg Finance L.P.
309//
310// Licensed under the Apache License, Version 2.0 (the "License");
311// you may not use this file except in compliance with the License.
312// You may obtain a copy of the License at
313//
314// http://www.apache.org/licenses/LICENSE-2.0
315//
316// Unless required by applicable law or agreed to in writing, software
317// distributed under the License is distributed on an "AS IS" BASIS,
318// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
319// See the License for the specific language governing permissions and
320// limitations under the License.
321// ----------------------------- END-OF-FILE ----------------------------------
322
323/** @} */
324/** @} */
325/** @} */
Definition ball_context.h:295
Definition ball_multiplexobserver.h:202
int numRegisteredObservers() const
Definition ball_multiplexobserver.h:296
void publish(const Record &record, const Context &context) BSLS_KEYWORD_OVERRIDE
~MultiplexObserver() BSLS_KEYWORD_OVERRIDE
int deregisterObserver(Observer *observer)
int registerObserver(Observer *observer)
void releaseRecords() BSLS_KEYWORD_OVERRIDE
Definition ball_observer.h:235
Definition ball_record.h:178
Definition bslstl_set.h:657
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this set.
Definition bslstl_set.h:2725
Definition bslma_allocator.h:457
Definition bslmt_rwmutex.h:147
Definition bslmt_readlockguard.h:287
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition ball_administration.h:214
Definition bdlb_printmethods.h:283
Definition balxml_encoderoptions.h:68