MySQL 8.4.0
Source Code Documentation
reference_caching.h
Go to the documentation of this file.
1/* Copyright (c) 2020, 2024, Oracle and/or its affiliates.
2
3This program is free software; you can redistribute it and/or modify
4it under the terms of the GNU General Public License, version 2.0,
5as published by the Free Software Foundation.
6
7This program is designed to work with certain software (including
8but not limited to OpenSSL) that is licensed under separate terms,
9as designated in a particular file or component or in included license
10documentation. The authors of MySQL hereby grant you an additional
11permission to link the program and your derivative works with the
12separately licensed software that they have either included with
13the program or referenced in the documentation.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License, version 2.0, for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef REFERENCE_CACHING_H
25#define REFERENCE_CACHING_H
26
29
30/**
31 Handle for "producer channels".
32 A producer channel is the singleton used to emit events that are subject
33 to reference caching.
34 This is needed to hold a flag that will trigger forced invalidation of all
35 caches in a particular channel on their next access.
36 Multi threaded access is expected to be safe and lock less to this handle
37 once it's instantiated.
38*/
40
41/**
42 A handle of a "reference cache". This is created by all events producer
43 threads when they start and is maintained throughout their lifetimes.
44 Operations on that are not thread safe and are assumed to be done by a
45 single thread.
46*/
48
49/**
50 @ingroup group_components_services_inventory
51*/
52
53/**
54 A reference caching channel service.
55
56 The goal of this service is to ensure that event producers spend
57 a MINIMAL amount of time in the emitting code when there are no consumers of
58 the produced events.
59
60 Terminology
61 -----------
62
63 An event consumer is an implementation of a component service.
64 An event producer is a piece of code that wants to inform all currently
65 registered event consumers about an event.
66 A channel is a device that serves as a singleton of all reference caches
67 for all threads that are to produce events.
68 A reference cache is something each thread producing events must maintain
69 for its lifetime and use it to find the references to event consumers it
70 needs to call.
71
72 Typical lifetime of the event consumers
73 ---------------------------------------
74
75 At init time the event consumer will register implementations of any of
76 the services it's interested in receiving notifications for.
77
78 Then optionally it might force a channel invalidation to make sure all
79 existing event producers will start sending notifications to it immediately.
80 Or it can just sit and wait for the natural producer's reference cache
81 refresh cycles to kick in.
82
83 Now it is receiving notifications from all event producers as they come.
84
85 When it wishes to no longer receive notifications it needs to mark itself
86 as invisible for reference cache fill-ins. In this way all reference cache
87 flushes will not pick this implementation up even if it's still registered
88 in the registry.
89
90 Eventually all active references will be removed by the natural producers
91 flush cycles.
92 The consumer may choose to expedite this by triggering a channel
93 invalidation.
94
95 As with all service implementations, when all references to the services
96 are released it can unload.
97
98 Typical lifetime of the event producers
99 ---------------------------------------
100
101 An event producer will usually start at init time by creating channel(s).
102
103 Then, for each thread wishing to produce events, a reference cache must
104 be created and maintained until the thread will no longer be producing
105 events.
106
107 Now the thread can produce events using the reference cache.
108 This is done by calling the get method and then iterating over the
109 resulting set of references and calling each one in turn as one would
110 normally do for registry service references.
111 It is assumed that the references are owned by the cache and thus they
112 should not be released.
113
114 With some cyclical (e.g. at the end of each statement or something)
115 the event producing thread needs to flush the cache. This is to ensure
116 that references to event consumers are not held for very long and that
117 new event consumers are picked up. However flushing the cache is a relatively
118 expensive operation and thus a balance between the number of events produced
119 and the cache being flushed must be achieved.
120
121 General remarks
122 ---------------
123
124 Channels are something each event producer must have to produce events.
125 Channels are to be created by a single thread before the first event is ever
126 produced. And, once created they are to be kept until after the last event is
127 produced.
128
129 Channels serve as singletons for caches and you only need one channel instance
130 per event producer component.
131 There usually will be multiple caches (one per event producing thread) per
132 channel.
133
134 Creating and destroying a channel is a relatively "expensive" operation that
135 might involve some synchronization and should not be done frequently.
136
137 Channels exist to allow a non-related thread to trigger invalidation of all
138 currently active caches on that channel. This is necessary when for example
139 event consumers are registered and are about to be removed.
140
141 Invalidating a channel is a thread-safe operation that can be invoked without
142 synchronization at any time.
143
144 Each channel is associated with a specific set of service names.
145 @note It is a set of service names, not implementation names !
146
147 The names are stored and used in event caches to handle all implementations
148 of that particular service.
149*/
151/**
152 Creates a channel and returns a handle for it.
153
154 The handle created by this method must be destroyed by the invalidate
155 method otherwise there might be leaks.
156
157 The channel should be created before any events are to be produced on it.
158
159 @param service_names a list of service names that this channel will operate
160 on. Terminated by a NULL pointer
161 @param[out] out_channel placeholder for the newly created handle.
162 @retval false success
163 @retval true failure
164*/
165DECLARE_BOOL_METHOD(create, (const char *service_names[],
167
168/**
169 Destroys a channel handle
170
171 Should make sure no other thread is using the handle and no caches are
172 allocated on it.
173
174 @param channel the handle to destroy
175 @retval false success
176 @retval true failure
177*/
179
180/**
181 Invalidate a channel
182
183 This is thread safe to call without synchronization
184 and relatively fast.
185
186 Forces an asynchronous flush on all caches that are allocated on
187 that channel when they're next accessed.
188
189 @param channel the handle to destroy
190 @retval false success
191 @retval true failure
192*/
194
196
197/**
198 A service to maintain an "ignore list" for reference caches.
199
200 When a service implementation is on that ignore list it will never be
201 added to any reference caches when they're filled in even if the service
202 implementation is in the registry and implements the service
203 the reference caching channel is operating on.
204
205 This is just a list of "implementations", i.e. the part of the service
206 implementation name after the dot.
207 The channel already has the name of the service so a full implementation
208 name can be constructed if needed.
209*/
210BEGIN_SERVICE_DEFINITION(reference_caching_channel_ignore_list)
211/**
212 Adds an implementation name to the ignore list.
213
214 @param channel the channel to add the ignored implementation to.
215 @param implementation_name the second part of the service implementation
216 name (the part after the dot).
217 @retval false successfully added
218 @retval true error adding (e.g. the ignore is present etc.
219*/
221 const char *implementation_name));
222/**
223 Remove an implementation name to the ignore list.
224
225 @param channel the channel to remove the ignored implementation from.
226 @param implementation_name the second part of the service implementation
227 name (the part after the dot).
228 @retval false successfully removed
229 @retval true error removing or not present
230*/
232 const char *implementation_name));
233/**
234 Empty the ignore list.
235
236 @param channel the channel to remove the ignored implementation from.
237 @retval false successfully removed all ignores
238 @retval true error removing the ignores. State unknown.
239*/
241END_SERVICE_DEFINITION(reference_caching_channel_ignore_list)
242
243/**
244 Reference cache service.
245
246 See the reference_caching_channel service for details on how to
247 operate this.
248
249 Manages thread caches for event producer threads.
250*/
252/**
253 Create a reference cache.
254
255 Needs to be called before the first get() or flush() is called.
256 Each call to create must be paired with a call to destroy() or
257 there will be leaks.
258
259 @param channel the reference cache channel to operate on.
260 @param registry a handle to the registry so that no time is spent taking it
261 @param[out] handle of the newly allocated cache.
262 @retval false success
263 @retval true failure
264*/
266 SERVICE_TYPE(registry) * registry,
268/**
269 Destroy a reference cache.
270
271 Needs to be called to dispose of each cache allocated by create().
272 Needs to be called after all possible calls to get() and flush().
273 Once called the cache handle is invalid and should not be used anymore.
274
275 @param channel the reference cache channel to operate on.
276 @param[out] handle of the newly allocated cache.
277 @retval false success
278 @retval true failure
279*/
281
282/**
283 Gets a set of service references for an event producer to call.
284
285 This is the main event producer function that will be called when the
286 event producer needs to produce an event.
287
288 The cache must be a valid one. And the channel too.
289
290 If the cache is empty or invalidated (either via the channel or via a call
291 to flush) it will try to fill it by consulting the registry and acquiring
292 references to all implementations of the service the channel is created for.
293 Once that is done the cache will be marked as full. This a cache "miss":
294 a relatively expensive operation and care must be taken so it doesn't
295 happen very often.
296
297 If the cache is full (not flushed) this call will return all references
298 stored into the cache (might be zero too).
299 This is a very fast operation since the cache is single-thread-use and thus
300 no synchronization will be done (except for checking the channel's state
301 of course). This is a cache "hit" and should be the normal operation of the
302 cache.
303
304 @param cache the cache to use
305 @param service_index to get references to. Must be one of the services the
306 channel serves
307 @param[out] an array of my_h_service terminated with an empty service (0).
308 @retval true failure
309 @retval false success
310*/
311DECLARE_BOOL_METHOD(get, (reference_caching_cache cache, unsigned service_index,
312 const my_h_service **refs));
313/**
314 Flush a reference cache
315
316 This causes the reference cache supplied to be flushed. When in this state
317 the next call to get() will be a guaranteed cache miss and will fill in the
318 cache.
319
320 @param cache the cache to flush
321 @retval true failure
322 @retval false success
323*/
326
327#endif /* REFERENCE_CACHING_H */
int destroy(azio_stream *s)
Definition: azio.cc:371
struct my_h_service_imp * my_h_service
A handle type for acquired Service.
Definition: registry.h:33
void get(PSI_field *, PSI_longlong *) noexcept
Definition: pfs_plugin_column_bigint_v1_all_empty.cc:32
static mysql_service_status_t flush(reference_caching_cache cache) noexcept
Definition: component.cc:114
static mysql_service_status_t remove(reference_caching_channel channel, const char *implementation_name) noexcept
Definition: component.cc:137
static mysql_service_status_t clear(reference_caching_channel channel) noexcept
Definition: component.cc:146
static mysql_service_status_t add(reference_caching_channel channel, const char *implementation_name) noexcept
Definition: component.cc:127
static mysql_service_status_t invalidate(reference_caching_channel channel) noexcept
Definition: component.cc:69
static mysql_service_status_t create(const char *service_names[], reference_caching_channel *out_channel) noexcept
Definition: component.cc:45
struct reference_caching_cache_imp * reference_caching_cache
A handle of a "reference cache".
Definition: reference_caching.h:47
struct reference_caching_channel_imp * reference_caching_channel
Handle for "producer channels".
Definition: reference_caching.h:39
#define SERVICE_TYPE(name)
Generates the standard Service type name.
Definition: service.h:76
#define END_SERVICE_DEFINITION(name)
A macro to end the last Service definition started with the BEGIN_SERVICE_DEFINITION macro.
Definition: service.h:91
#define BEGIN_SERVICE_DEFINITION(name)
Declares a new Service.
Definition: service.h:86
#define DEFINE_SERVICE_HANDLE(name)
Defines an object type that is meant for carrying handles to the implementation-specific objects used...
Definition: service.h:129
#define DECLARE_BOOL_METHOD(name, args)
Declares a method that returns bool as a part of the Service definition.
Definition: service.h:112
Definition: task.h:427