I have a use case where I want to keep a pre-compiled regex, cached, for performance reasons, but the regex pattern also needs to be updated infrequently. Instances of CachedRegexFilter class will be used by multiple threads. The actual pattern for the regex is supplied as a custom class, StringConfig, which is basically a global volatile string that can be updated by a different thread.
Example usage:
// Main thread:
StringConfig regex = new StringConfig() { Value = ".*"};
CachedRegexFilter filter = new CachedRegexFilter(regex);
// now the filter is passed on to multiple service classes
MyApi(apiFilter: filter);
MyCron(cronFilter: filter);
//The config is updated by a seperate service
ConfigUpdaterSerice(configToUpdate: regex);
I have come up with this solution but would appreciate a review to ensure it is truly thread safe!
// a thread safe class for filtering strings based on a dynamic regex represented by a StringConfig
public class CachedRegexFilter
{
private readonly StringConfig _overrideRegex;
private readonly object _regexReplaceLock = new object();
private volatile string _currentoverrideRegexPattern;
private volatile Regex _currentoverrideRegex;
public CachedRegexFilter(StringConfig overrideRegex)
{
_overrideRegex = Preconditions.IsNotNull(overrideRegex, nameof(overrideRegex)); ;
UpdateCachedPattern();
}
public bool Matches(string toMatch)
{
if (_currentoverrideRegexPattern != _overrideRegex.Value)
{
lock (_regexReplaceLock)
{
// now entering critical section. Check again
if (_currentoverrideRegexPattern != _overrideRegex.Value)
{
UpdateCachedPattern();
}
}
}
return _currentoverrideRegex?.IsMatch(toMatch) ?? false;
}
private void UpdateCachedPattern()
{
_currentoverrideRegexPattern = _overrideRegex.Value;
_currentoverrideRegex = string.IsNullOrEmpty(_currentoverrideRegexPattern)
? null
: new Regex(_currentoverrideRegexPattern, RegexOptions.Singleline | RegexOptions.Compiled);
}
}
CachedRegexFilter
, which will be used on multiple threads. What happens tofilter
instance afterConfigUpdaterSerice
is finished? \$\endgroup\$