From 1b516331a8a145dcb565630fa3b3dd5777ae6b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20=C5=81abu=C5=9B?= Date: Sat, 13 Jul 2019 01:26:17 +0200 Subject: [PATCH 1/3] Updated .gitignore --- .gitignore | 267 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 230 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index 2f72fc4..846c8c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,34 +1,79 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files +*.rsuser *.suo *.user +*.userosscache *.sln.docstates -# Build results +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* +# Build results [Dd]ebug/ +[Dd]ebugPublic/ [Rr]elease/ +[Rr]eleases/ x64/ -build/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ [Bb]in/ [Oo]bj/ +[Ll]og/ -# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets -!packages/*/build/ +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio *_i.c *_p.c +*_h.h *.ilk *.meta *.obj +*.iobj *.pch *.pdb +*.ipdb *.pgc *.pgd *.rsp @@ -38,26 +83,40 @@ build/ *.tlh *.tmp *.tmp_proj +*_wpftmp.csproj *.log *.vspscc *.vssscc .builds *.pidb -*.log +*.svclog *.scc +# Chutzpah Test files +_Chutzpah* + # Visual C++ cache files ipch/ *.aps *.ncb +*.opendb *.opensdf *.sdf *.cachefile +*.VC.db +*.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ # Guidance Automation Toolkit *.gpState @@ -65,6 +124,10 @@ ipch/ # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode # TeamCity is a build add-in _TeamCity* @@ -72,9 +135,25 @@ _TeamCity* # DotCover is a Code Coverage Tool *.dotCover +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + # NCrunch -*.ncrunch* +_NCrunch_* .*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ # Installshield output folder [Ee]xpress/ @@ -93,64 +172,178 @@ DocProject/Help/html publish/ # Publish Web Output -*.Publish.xml +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj -# NuGet Packages Directory -## TODO: If you have NuGet Package Restore enabled, uncomment the next line -packages/ +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ -# Windows Azure Build Output -csx +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ *.build.csdef -# Windows Store app package directory +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ # Others -sql/ -*.Cache ClientBin/ -[Ss]tyle[Cc]op.* ~$* *~ *.dbmdl -*.[Pp]ublish.xml +*.dbproj.schemaview +*.jfm *.pfx *.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ # RIA/Silverlight projects Generated_Code/ -# Backup & report files from converting an old project file to a newer -# Visual Studio version. Backup files are not needed, because we have git ;-) +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak # SQL Server files -App_Data/*.mdf -App_Data/*.ldf +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ +# Azure Stream Analytics local run output +ASALocalRun/ -#LightSwitch generated files -GeneratedArtifacts/ -_Pvt_Extensions/ -ModelManifest.xml +# MSBuild Binary and Structured Log +*.binlog -# ========================= -# Windows detritus -# ========================= +# NVidia Nsight GPU debugger configuration file +*.nvuser -# Windows image file caches -Thumbs.db -ehthumbs.db +# MFractors (Xamarin productivity tool) working folder +.mfractor/ -# Folder config file -Desktop.ini +# Local History for Visual Studio +.localhistory/ -# Recycle Bin used on file shares -$RECYCLE.BIN/ +# BeatPulse healthcheck temp database +healthchecksdb -# Mac desktop service store files -.DS_Store +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ \ No newline at end of file From f1132575bb9f400daeec8358ecb350b3dcc4ce34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20=C5=81abu=C5=9B?= Date: Fri, 26 Jul 2019 11:04:59 +0200 Subject: [PATCH 2/3] Added OnStatusChange event --- RedLockNet.Abstractions/IRedLock.cs | 5 ++ .../Events/RedLockStatusChangedEventArgs.cs | 16 +++++ RedLockNet.SERedis/RedLock.cs | 64 ++++++++++++------- 3 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 RedLockNet.SERedis/Events/RedLockStatusChangedEventArgs.cs diff --git a/RedLockNet.Abstractions/IRedLock.cs b/RedLockNet.Abstractions/IRedLock.cs index f939772..3b611d9 100644 --- a/RedLockNet.Abstractions/IRedLock.cs +++ b/RedLockNet.Abstractions/IRedLock.cs @@ -33,5 +33,10 @@ public interface IRedLock : IDisposable /// The number of times the lock has been extended. /// int ExtendCount { get; } + + /// + /// Triggered whenever status property changes. + /// + event EventHandler OnStatusChanged; } } \ No newline at end of file diff --git a/RedLockNet.SERedis/Events/RedLockStatusChangedEventArgs.cs b/RedLockNet.SERedis/Events/RedLockStatusChangedEventArgs.cs new file mode 100644 index 0000000..a70bc82 --- /dev/null +++ b/RedLockNet.SERedis/Events/RedLockStatusChangedEventArgs.cs @@ -0,0 +1,16 @@ +using System; + +namespace RedLockNet.SERedis.Events +{ + public class RedLockStatusChangedEventArgs : EventArgs + { + public T OldValue { get; } + public T NewValue { get; } + + public RedLockStatusChangedEventArgs(T oldValue, T newValue) + { + OldValue = oldValue; + NewValue = newValue; + } + } +} diff --git a/RedLockNet.SERedis/RedLock.cs b/RedLockNet.SERedis/RedLock.cs index 56bb6cd..258b306 100644 --- a/RedLockNet.SERedis/RedLock.cs +++ b/RedLockNet.SERedis/RedLock.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using RedLockNet.SERedis.Events; using RedLockNet.SERedis.Internal; using RedLockNet.SERedis.Util; using StackExchange.Redis; @@ -26,7 +27,9 @@ public class RedLock : IRedLock private readonly double clockDriftFactor; private bool isDisposed; - private Timer lockKeepaliveTimer; + private Timer lockKeepAliveTimer; + + private RedLockStatus status; private static readonly string UnlockScript = EmbeddedResourceLoader.GetEmbeddedResource("RedLockNet.SERedis.Lua.Unlock.lua"); @@ -37,11 +40,26 @@ public class RedLock : IRedLock public string Resource { get; } public string LockId { get; } public bool IsAcquired => Status == RedLockStatus.Acquired; - public RedLockStatus Status { get; private set; } - public RedLockInstanceSummary InstanceSummary { get; private set; } - public int ExtendCount { get; private set; } - - private readonly TimeSpan expiryTime; + public event EventHandler OnStatusChanged; + public RedLockInstanceSummary InstanceSummary { get; private set; } + public int ExtendCount { get; private set; } + + public RedLockStatus Status + { + get => status; + private set + { + if (status == value) + return; + + var old = status; + status = value; + + OnStatusChanged?.Invoke(this, new RedLockStatusChangedEventArgs(old, status)); + } + } + + private readonly TimeSpan expiryTime; private readonly TimeSpan? waitTime; private readonly TimeSpan? retryTime; private CancellationToken cancellationToken; @@ -94,8 +112,8 @@ internal static RedLock Create( TimeSpan expiryTime, TimeSpan? waitTime = null, TimeSpan? retryTime = null, - CancellationToken? cancellationToken = null) - { + CancellationToken? cancellationToken = null) + { var redisLock = new RedLock( logger, redisCaches, @@ -117,8 +135,8 @@ internal static async Task CreateAsync( TimeSpan expiryTime, TimeSpan? waitTime = null, TimeSpan? retryTime = null, - CancellationToken? cancellationToken = null) - { + CancellationToken? cancellationToken = null) + { var redisLock = new RedLock( logger, redisCaches, @@ -233,12 +251,12 @@ private async Task StartAsync() } } - var status = GetFailedRedLockStatus(lockSummary); + var failedStatus = GetFailedRedLockStatus(lockSummary); // give up logger.LogDebug($"Could not acquire quorum after {quorumRetryCount} attempts, giving up: {Resource} ({LockId}). {lockSummary}."); - return (status, lockSummary); + return (failedStatus, lockSummary); } private async Task<(RedLockStatus, RedLockInstanceSummary)> AcquireAsync() @@ -279,12 +297,12 @@ private async Task StartAsync() } } - var status = GetFailedRedLockStatus(lockSummary); + var failedStatus = GetFailedRedLockStatus(lockSummary); // give up logger.LogDebug($"Could not acquire quorum after {quorumRetryCount} attempts, giving up: {Resource} ({LockId}). {lockSummary}."); - return (status, lockSummary); + return (failedStatus, lockSummary); } private void StartAutoExtendTimer() @@ -293,7 +311,7 @@ private void StartAutoExtendTimer() logger.LogDebug($"Starting auto extend timer with {interval}ms interval"); - lockKeepaliveTimer = new Timer( + lockKeepAliveTimer = new Timer( state => { try @@ -565,11 +583,11 @@ protected virtual void Dispose(bool disposing) { lock (lockObject) { - if (lockKeepaliveTimer != null) + if (lockKeepAliveTimer != null) { - lockKeepaliveTimer.Change(Timeout.Infinite, Timeout.Infinite); - lockKeepaliveTimer.Dispose(); - lockKeepaliveTimer = null; + lockKeepAliveTimer.Change(Timeout.Infinite, Timeout.Infinite); + lockKeepAliveTimer.Dispose(); + lockKeepAliveTimer = null; } } } @@ -629,14 +647,14 @@ private static RedLockInstanceSummary PopulateRedLockResult(IEnumerable internal void StopKeepAliveTimer() { - if (lockKeepaliveTimer == null) - { + if (lockKeepAliveTimer == null) + { return; } logger.LogDebug("Stopping auto extend timer"); - lockKeepaliveTimer.Change(Timeout.Infinite, Timeout.Infinite); + lockKeepAliveTimer.Change(Timeout.Infinite, Timeout.Infinite); } - } + } } From c1ef63059744b6c663c4963111cd47b83ef473c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20=C5=81abu=C5=9B?= Date: Fri, 26 Jul 2019 11:08:09 +0200 Subject: [PATCH 3/3] Adjusted code-style --- RedLockNet.Abstractions/IRedLock.cs | 8 +-- .../Events/RedLockStatusChangedEventArgs.cs | 20 +++---- RedLockNet.SERedis/RedLock.cs | 52 +++++++++---------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/RedLockNet.Abstractions/IRedLock.cs b/RedLockNet.Abstractions/IRedLock.cs index 3b611d9..413e9f0 100644 --- a/RedLockNet.Abstractions/IRedLock.cs +++ b/RedLockNet.Abstractions/IRedLock.cs @@ -34,9 +34,9 @@ public interface IRedLock : IDisposable /// int ExtendCount { get; } - /// - /// Triggered whenever status property changes. - /// - event EventHandler OnStatusChanged; + /// + /// Triggered whenever status property changes. + /// + event EventHandler OnStatusChanged; } } \ No newline at end of file diff --git a/RedLockNet.SERedis/Events/RedLockStatusChangedEventArgs.cs b/RedLockNet.SERedis/Events/RedLockStatusChangedEventArgs.cs index a70bc82..99555e7 100644 --- a/RedLockNet.SERedis/Events/RedLockStatusChangedEventArgs.cs +++ b/RedLockNet.SERedis/Events/RedLockStatusChangedEventArgs.cs @@ -2,15 +2,15 @@ namespace RedLockNet.SERedis.Events { - public class RedLockStatusChangedEventArgs : EventArgs - { - public T OldValue { get; } - public T NewValue { get; } + public class RedLockStatusChangedEventArgs : EventArgs + { + public T OldValue { get; } + public T NewValue { get; } - public RedLockStatusChangedEventArgs(T oldValue, T newValue) - { - OldValue = oldValue; - NewValue = newValue; - } - } + public RedLockStatusChangedEventArgs(T oldValue, T newValue) + { + OldValue = oldValue; + NewValue = newValue; + } + } } diff --git a/RedLockNet.SERedis/RedLock.cs b/RedLockNet.SERedis/RedLock.cs index 258b306..402c59d 100644 --- a/RedLockNet.SERedis/RedLock.cs +++ b/RedLockNet.SERedis/RedLock.cs @@ -29,7 +29,7 @@ public class RedLock : IRedLock private Timer lockKeepAliveTimer; - private RedLockStatus status; + private RedLockStatus status; private static readonly string UnlockScript = EmbeddedResourceLoader.GetEmbeddedResource("RedLockNet.SERedis.Lua.Unlock.lua"); @@ -40,26 +40,26 @@ public class RedLock : IRedLock public string Resource { get; } public string LockId { get; } public bool IsAcquired => Status == RedLockStatus.Acquired; - public event EventHandler OnStatusChanged; - public RedLockInstanceSummary InstanceSummary { get; private set; } - public int ExtendCount { get; private set; } - - public RedLockStatus Status - { - get => status; - private set - { - if (status == value) - return; - - var old = status; - status = value; - - OnStatusChanged?.Invoke(this, new RedLockStatusChangedEventArgs(old, status)); - } - } - - private readonly TimeSpan expiryTime; + public event EventHandler OnStatusChanged; + public RedLockInstanceSummary InstanceSummary { get; private set; } + public int ExtendCount { get; private set; } + + public RedLockStatus Status + { + get => status; + private set + { + if (status == value) + return; + + var old = status; + status = value; + + OnStatusChanged?.Invoke(this, new RedLockStatusChangedEventArgs(old, status)); + } + } + + private readonly TimeSpan expiryTime; private readonly TimeSpan? waitTime; private readonly TimeSpan? retryTime; private CancellationToken cancellationToken; @@ -112,8 +112,8 @@ internal static RedLock Create( TimeSpan expiryTime, TimeSpan? waitTime = null, TimeSpan? retryTime = null, - CancellationToken? cancellationToken = null) - { + CancellationToken? cancellationToken = null) + { var redisLock = new RedLock( logger, redisCaches, @@ -135,8 +135,8 @@ internal static async Task CreateAsync( TimeSpan expiryTime, TimeSpan? waitTime = null, TimeSpan? retryTime = null, - CancellationToken? cancellationToken = null) - { + CancellationToken? cancellationToken = null) + { var redisLock = new RedLock( logger, redisCaches, @@ -656,5 +656,5 @@ internal void StopKeepAliveTimer() lockKeepAliveTimer.Change(Timeout.Infinite, Timeout.Infinite); } - } + } }