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