BDE 4.39.x 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 <span style="color: var(--deprecated-color-dark)">DEPRECATED:</span> 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 private:
211 // NOT IMPLEMENTED
213 MultiplexObserver& operator=(const MultiplexObserver&);
214
215 public:
216 // CREATORS
217
218 /// Create a multiplexing observer having no registered observers.
219 /// Optionally specify a `basicAllocator` used to supply memory. If
220 /// `basicAllocator` is 0, the currently installed default allocator is
221 /// used.
222 explicit MultiplexObserver(bslma::Allocator *basicAllocator = 0);
223
224 /// Destroy this multiplexing observer.
225 /// \note Note that this method has no
226 /// effect on the lifetime of observers registered with this observer, if
227 /// any.
229
230 // MANIPULATORS
231
232 /// Process the specified log `record` having the specified publishing
233 /// `context` by forwarding `record` and `context` to each of the
234 /// observers registered with this multiplexing observer.
235 ///
236 /// @deprecated Use the alternative `publish` overload instead.
237 void publish(const Record& record,
238 const Context& context) BSLS_KEYWORD_OVERRIDE;
239
240 /// Process the specified log `record` having the specified publishing
241 /// `context`. This concrete publish implementations processes the
242 /// `record` by forwarding `record` and `context` to each of the
243 /// observers registered with this multiplexing observer.
244 void publish(const bsl::shared_ptr<const Record>& record,
245 const Context& context)
247
248 /// Discard any shared reference to a `Record` object that was supplied
249 /// to the `publish` method, and is held by this observer. This
250 /// implementation processes `releaseRecords` by calling
251 /// `releaseRecords` on each of the registered observers.
252 ///
253 /// \note Note that this operation should be called if resources underlying the
254 /// previously provided shared pointers must be released.
256
257 /// Add the specified `observer` to the registry of this multiplexing
258 /// observer. Return 0 if `observer` is non-null and was not already
259 /// registered with this multiplexing observer, and a non-zero value
260 /// (with no effect) otherwise. Henceforth, this multiplexing observer
261 /// will forward each record it receives through its `publish` method,
262 /// including the record's context, to the `publish` method of
263 /// `observer`, until `observer` is deregistered.
264 ///
265 /// \pre The behavior is undefined unless `observer` remains valid until it is deregistered
266 /// from this multiplexing observer or until this observer is destroyed.
268
269 /// Remove the specified `observer` from the registry of this
270 /// multiplexing observer. Return 0 if `observer` is non-null and was
271 /// registered with this multiplexing observer, and a non-zero value
272 /// (with no effect) otherwise. Henceforth, `observer` will no longer
273 /// receive log records from this multiplexing observer.
275
276 // ACCESSORS
277
278 /// Return the number of observers registered with this multiplexing
279 /// observer.
280 int numRegisteredObservers() const;
281};
282
283// ============================================================================
284// INLINE DEFINITIONS
285// ============================================================================
286
287 // -----------------------
288 // class MultiplexObserver
289 // -----------------------
290
291// CREATORS
292inline
293MultiplexObserver::MultiplexObserver(bslma::Allocator *basicAllocator)
294: d_observerSet(basicAllocator)
295{
296}
297
298// ACCESSORS
299inline
301{
302 bslmt::ReadLockGuard<bslmt::RWMutex> guard(&d_rwMutex);
303 return static_cast<int>(d_observerSet.size());
304}
305
306} // close package namespace
307
308
309#endif
310
311// ----------------------------------------------------------------------------
312// Copyright 2015 Bloomberg Finance L.P.
313//
314// Licensed under the Apache License, Version 2.0 (the "License");
315// you may not use this file except in compliance with the License.
316// You may obtain a copy of the License at
317//
318// http://www.apache.org/licenses/LICENSE-2.0
319//
320// Unless required by applicable law or agreed to in writing, software
321// distributed under the License is distributed on an "AS IS" BASIS,
322// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
323// See the License for the specific language governing permissions and
324// limitations under the License.
325// ----------------------------- END-OF-FILE ----------------------------------
326
327/** @} */
328/** @} */
329/** @} */
Definition ball_context.h:297
Definition ball_multiplexobserver.h:202
int numRegisteredObservers() const
Definition ball_multiplexobserver.h:300
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:176
Definition bslstl_set.h:691
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this set.
Definition bslstl_set.h:3227
Definition bslma_allocator.h:545
Definition bslmt_rwmutex.h:148
Definition bslmt_readlockguard.h:287
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
Definition ball_administration.h:214
Definition bdlat_valuetypefunctions.h:939
Definition baljsn_encoder_testtypes.h:76