A deadlock can happen when a sorcery object is being expired from the
memory cache when at the same time another object is being placed into the
memory cache. There are a couple other variations on this theme that
could cause the deadlock. Basically if an object is being expired from
the sorcery memory cache at the same time as another thread tries to
update the next object expiration timer the deadlock can happen.
* Add a deadlock avoidance loop in expire_objects_from_cache() to check if
someone is trying to remove the scheduler callback from the scheduler.
ASTERISK-25441 #close
Change-Id: Iec7b0bdb81a72b39477727b1535b2539ad0cf4dc
Make sorcery_memory_cache_close() call remove_all_from_cache() instead of
partially inlining it.
ASTERISK-25441
Change-Id: I1aa6cb425b1a4307096f3f914d17af8ec179a74c
Basically you should shutdown in the opposite order of how you setup since
later setup pieces likely depend on earlier setup pieces. e.g.,
Registering your external API with the rest of the system should be the
last thing setup and the first thing unregistered during shutdown.
Change-Id: I5715765b723100c8d3c2642e9e72cc7ad5ad115e
In Jenkins there is currently a sporadic test failure of a
variable number of sorcery memory cache unit tests. I have not
been able to reproduce this on the build agents themselves or
on my development machine.
My working theory is that the stale unit test is causing a
sorcery instance to persist longer than expected, causing subsequent
tests to fail when setting up and initializing the next
sorcery instance.
To see if this is the case this change moves the stale unit test
to execute last so no subsequent unit tests can have issues
initializing their sorcery instance.
Change-Id: Ifd6550a949613be774b75fa5db12c02110f82c4a
Analyzing the code shows that the unit test summary and description
strings should not end with a new-line character. Where these strings are
used in the code a new-line is provided for output.
Change-Id: I2f4f37988ec363c8d1c5077a2fc8ca841c5cd30c
To prevent confusion I am removing the prefetch option until such
time as it is implemented. All other functionality, however, has
been implemented.
ASTERISK-25067
Change-Id: I9ce6aa3e5c6c5bc3c5baa8ff90fa036d73939895
This change implements the expire_on_reload option for memory caches.
If enabled and a reload is performed all objects within the cache
will be expired and the cache emptied.
ASTERISK-25067
Reported by: Matt Jordan
Change-Id: Id46aa1957d660556700e689e195eed57c989b85e
This change adds a CLI command which can perform memory cache thrashing as well
as unit tests which perform thrashing under the following configurations:
1. Low number of unique objects that go stale after 1 second
2. Low number of unique objects that expire after 1 second
3. Low number of unique objects which are constantly updated
4. Large number of unique objects which exceed a defined cache size
5. Large number of unique objects which exceed a defined cache size
that also expire and go stale rapidly
6. Large number of unique objects which expire and go stale rapidly
7. Large number of unique objects
For all of the above there are a large number of threads constantly
attempting to retrieve random objects and each test runs for a few
seconds.
ASTERISK-25067
Reported by: Matt Jordan
Change-Id: I8c8ceff977332c80ed4a31f10d694d48552b2f78
This change adds a testsuite event for when a refresh occurs.
This is useful as it provides a guaranteed mechanism of knowing when
it has occurred instead of waiting an arbitrary amount of time.
ASTERISK-25067
Reported by: Matt Jordan
Change-Id: Iaa6b8d2d6bab7f99ee08e1c8908b8272a8987e65
This change adds the following CLI commands and AMI actions:
sorcery memory cache show
sorcery memory cache dump
sorcery memory cache expire
sorcery memory cache stale
SorceryMemoryCacheExpire
SorceryMemoryCacheExpireObject
SorceryMemoryCacheStale
SorceryMemoryCacheStaleObject
These allow both examination and manipulation of sorcery memory
caches from external sources.
Cached objects can be explicitly expired from a cache or marked
as stale. If expired they are immediately removed. If marked as
stale they will be background refreshed when next retrieved.
ASTERISK-25067
Reported by Matt Jordan
Change-Id: I68e03cfd8c34b5e07f4b6ee4fd93a3f4a00a3d9e
This change introduces a check of object_lifetime_stale when retrieving
cached objects. If the amount of time the object has been in the cache
exceeds the lifetime, then a task is scheduled to update the cached
object based on an object retrieved from other sorcery wizards instead.
To prevent the cached object from being retrieved during a refresh,
thread-local storage is used to mark the thread as being a stale object
update. This results in the cache returning no object, leading to
sorcery querying other wizards for the object instead.
A test has been added for stale objects as well. This test ensures that
stale objects are retrieved the same as freshly-cached objects. The test
also ensures that after an object is stale, changes in the backend are
reflected in the cache, to include if the object has been deleted from
the backend.
ASTERISK-25067
Reported by Matt Jordan
Change-Id: I9bd7c049adf6939bfe2899f393c2bfbbf412d217
This makes the "object_lifetime_maximum" option operational.
On the addition of an object to an empty memory cache a scheduled
task is created which, when invoked, expires objects from the cache
which have exceeded their lifetime. If more objects have been added
the remaining life of the oldest object is used to schedule the
next invocation of the scheduled task.
If the oldest object is removed from the cache before it can be
expired automatically the scheduled task is cancelled, if possible,
and the lifetime of the next oldest is used to schedule the task.
If during these two operations no additional objects exist in the
cache then no task is scheduled.
An additional unit test has been added which verifies this
functionality.
ASTERISK-25067
Reported by: Matt Jordan
Change-Id: I87409674674a508e7717ee20739ca15cec6ba7b6
This makes the "maximum_objects" option operational.
A heap has been added alongside the hash table in the cache. When
objects are added to the cache, they are also added to the heap.
Similarly, when objects are removed from the cache, they are removed
from the heap.
The heap's use comes into play when an item is to be added to a "full"
cache. When the cache is full, the oldest item is removed from the
cache, using the heap to determine the oldest item.
A unit test has been added that verifies that the maximum_objects option
works as expected and that the oldest object is removed from the cache
when an object beyond the maximum is added.
ASTERISK-25067 #close
Reported by Matt Jordan
Change-Id: I490658830e9c4cbf0b3051e4cdc4913cf9f1b73a
This change adds a basic res_sorcery_memory_cache module which implements
configuration option parsing, configuration file parsing for threading,
sorcery interface implementation, and unit tests.
Objects can be added, updated, deleted, and retrieved from the memory
cache. Automatic expiration and stale handling will be added in the
future.
Note that unit tests exist within the module itself in case the
threading done as a result of expiration results in asynchronous
actions (which it likely will). Providing access and a notification
mechanism for an external test module would be complicated and
not worth it.
ASTERISK-25067 #close
Reported by: Matt Jordan
Change-Id: Id8a6a357ef5a83d466f81eee56a67d13eeb118b9