Skip to content

Instantly share code, notes, and snippets.

@msx752
Created December 5, 2020 23:24
Show Gist options
  • Save msx752/75e0008bbffbdb02b49869066a58c624 to your computer and use it in GitHub Desktop.
Save msx752/75e0008bbffbdb02b49869066a58c624 to your computer and use it in GitHub Desktop.
SignalR Cache Service (Experimental Thread Safe Caching)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SignalRCacheService.ConsoleApp
{
class Program
{
static void Main(string[] args)
{
SignalRCacheClient cacheClient = new SignalRCacheClient();
cacheClient.Connect();
var val = cacheClient.Set("IncrementDecrementTest", 0);
Console.WriteLine("start value: " + val);
Task.Run(() =>
{
Task.Run(() =>
{
for (int i2 = 0; i2 < 1000; i2++)
{
Console.WriteLine(cacheClient.Increment("IncrementDecrementTest", 2));
}
});
Task.Run(() =>
{
for (int i2 = 0; i2 < 1000; i2++)
{
Console.WriteLine(cacheClient.Increment("IncrementDecrementTest", 1));
}
});
});
Task.Run(() =>
{
for (int i = 0; i < 1000; i++)
{
Console.WriteLine(cacheClient.Decrement("IncrementDecrementTest", 1));
}
});
Task.Run(() =>
{
for (int i = 0; i < 1000; i++)
{
Console.WriteLine(cacheClient.Decrement("IncrementDecrementTest", 2));
}
});
Console.ReadLine();
}
}
}
using Microsoft.AspNet.SignalR.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SignalRCacheService.ConsoleApp
{
public class SignalRCacheClient
{
private HubConnection connection;
private IHubProxy hub;
public string[] AllKeys()
{
return hub.Invoke<string[]>("AllKeys").Result;
}
public void Connect(string signalrService = "https://localhost:44325/")
{
connection = new HubConnection(signalrService);
hub = connection.CreateHubProxy("SignalRCacheHub");
connection.Start().Wait();
}
public object Decrement(string key, long decrementBy = 1)
{
return hub.Invoke<object>("Decrement", key, decrementBy).Result;
}
public object Get(string key)
{
return hub.Invoke<object>("Get", key).Result;
}
public object Increment(string key, long incrementBy = 1)
{
return hub.Invoke<object>("Increment", key, incrementBy).Result;
}
public string[] KeyContains(string search)
{
return hub.Invoke<string[]>("KeyContains", search).Result;
}
public string[] KeyStartWith(string search)
{
return hub.Invoke<string[]>("KeyStartWith", search).Result;
}
public object Remove(string key)
{
return hub.Invoke<object>("Remove", key).Result;
}
public object Set(string key, object value)
{
return hub.Invoke<object>("Set", key, value).Result;
}
}
}
using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
namespace SignalRCacheService
{
public class SignalRCacheHub : Hub
{
private static Lazy<ConcurrentDictionary<string, object>> lazyCache = new Lazy<ConcurrentDictionary<string, object>>();
public static ConcurrentDictionary<string, object> Cache { get { return lazyCache.Value; } }
public string[] AllKeys()
{
return Cache.Keys.ToArray();
}
public object Decrement(string key, long decrementBy = 1)
{
if (string.IsNullOrWhiteSpace(key))
return null;
if (decrementBy < 1)
decrementBy = 1;
if (!Cache.TryGetValue(key, out object result))
return null;
var returnVal = Cache.AddOrUpdate(key, decrementBy, (k, oldVal) =>
{
var oldValCasting = (long)oldVal;
long decrementedNewVal = 0;
for (int i = 0; i < decrementBy; i++)
decrementedNewVal = Interlocked.Decrement(ref oldValCasting);
return decrementedNewVal;
});
return returnVal;
}
public object Get(string key)
{
if (string.IsNullOrWhiteSpace(key))
return null;
Cache.TryGetValue(key, out object result);
return result;
}
public object Increment(string key, long incrementBy = 1)
{
if (string.IsNullOrWhiteSpace(key))
return null;
if (incrementBy < 1)
incrementBy = 1;
if (!Cache.TryGetValue(key, out object result))
return null;
var returnVal = Cache.AddOrUpdate(key, incrementBy, (k, oldVal) =>
{
var oldValCasting = (long)oldVal;
long incrementedNewVal = 0;
for (int i = 0; i < incrementBy; i++)
incrementedNewVal = Interlocked.Increment(ref oldValCasting);
return incrementedNewVal;
});
return returnVal;
}
public string[] KeyContains(string key)
{
return AllKeys().Where(f => f.Contains(key)).ToArray();
}
public string[] KeyStartWith(string key)
{
return AllKeys().Where(f => f.StartsWith(key, StringComparison.InvariantCultureIgnoreCase)).ToArray();
}
public object Remove(string key)
{
if (string.IsNullOrWhiteSpace(key))
return null;
Cache.TryRemove(key, out object result);
return result;
}
public object Set(string key, object value)
{
if (string.IsNullOrWhiteSpace(key))
return null;
var val = Cache.AddOrUpdate(key, value, (k, v) => value);
return val;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment