I send three http requests to a web service every 10th second. The reponses are handed off to three methods in a cache class (one for each http query / request) that checks whether the reponse content has changed since last time.
I convert the raw reponse content to a string and compare it to the old response, which is stored as a private string in the cache class. It works alright, but the approach has a lot of duplicate code, as you can see:
class Cache
{
private HubClient _hubClient;
private string oldIncidentAppointment;
private string oldIncidentGeneral;
private string oldIncidentUntreated;
public Cache(HubClient hubClient)
{
_hubClient = hubClient;
}
public bool IsIncidentAppointmentNew(string currentIncidentAppointment)
{
if (XElement.Equals(oldIncidentAppointment, currentIncidentAppointment))
{
return false;
}
else
{
oldIncidentAppointment = currentIncidentAppointment;
_hubClient.SendToHub();
return true;
}
}
public bool IsIncidentUntreatedNew(string currentIncidentUntreated)
{
if (XElement.Equals(oldIncidentUntreated, currentIncidentUntreated))
{
return false;
}
else
{
oldIncidentUntreated = currentIncidentUntreated;
_hubClient.SendToHub();
return true;
}
}
public bool IsIncidentGeneralNew(string currentIncidentGeneral)
{
if (XElement.Equals(oldIncidentGeneral, currentIncidentGeneral))
{
return false;
}
else
{
oldIncidentGeneral = currentIncidentGeneral;
_hubClient.SendToHub();
return true;
}
}
}
How can this be refactored into a generalized method that compares old and new content for all my current and future http query methods?
You can store them in a dictionary:
class Cache {
private HubClient _hubClient;
private Dictionary<string, string> _pages;
public Cache(HubClient hubClient)
{
_hubClient = hubClient;
_pages = new Dictionary<string, string>();
}
public bool isPageNew( string key, string content ) {
string current;
if (_pages.TryGetValue(key, out current) && XElement.Equals(current, content)) {
return false;
}
_pages[key] = content;
_hubClient.SendToHub(); //Why have side effect here? :P
return true;
}
}
Then:
Cache cache = new Cache( client );
if( cache.isPageNew( "untreated", pageContent ) ) {
}
This is quick and dirty, so if it's not 100% you'll have to fix it up; I don't have your tests to verify it's correctness. I'm also not sure you can just ask a dictionary for a key that doesn't exist without checking for it's existence, so you might have to handle that.
class Cache
{
private HubClient _hubClient;
private IDictionary<string, string> _oldIncidents;
public Cache(HubClient hubClient)
{
_hubClient = hubClient;
_oldIncidents = new Dictionary<string, string>();
}
public bool IsIncidentAppointmentNew(string currentIncidentAppointment)
{
return DoMagicWork(
incidentKey: "appointment",
currentIncident = currentIncidentAppointment
);
}
public bool IsIncidentUntreatedNew(string currentIncidentUntreated)
{
return DoMagicWork(
incidentKey: "untreated",
currentIncident = currentIncidentUntreated
);
}
public bool IsIncidentGeneralNew(string currentIncidentGeneral)
{
return DoMagicWork(
incidentKey: "general",
currentIncident = currentIncidentGeneral
);
}
private bool DoMagicWork(string incidentKey, string currentIncident)
{
var oldIncident = _oldIncidents[incidentKey];
if (XElement.Equals(oldIncident, currentIncident))
{
return false;
}
_oldIncidents[incidentKey] = currentIncident;
_hubClient.SendToHub();
return true;
}
}
Related
Well, I would like to do my own benchmarking system like spark in Minecraft (https://github.com/lucko/spark):
I'm using Harmony lib (https://github.com/pardeike/Harmony) which allows me to interact/modify methods and allows me to add a Prefix/Postfix on each call that will help me out with this stack.
The basic structure has something similar to (https://github.com/pardeike/Harmony/issues/355):
[HarmonyPatch]
class MyPatches
{
static IEnumerable<MethodBase> TargetMethods()
{
return AccessTools.GetTypesFromAssembly(Assembly.GetExecutingAssembly())
.SelectMany(type => type.GetMethods())
.Where(method => method.ReturnType != typeof(void) && method.Name.StartsWith("Do"));
}
static void Prefix(out Stopwatch __state, MethodBase __originalMethod)
{
__state = Stopwatch.StartNew();
// ...
}
static void Postfix(Stopwatch __state, MethodBase __originalMethod)
{
__state.Stop();
// ....
}
}
The problem here is that the __originalMethod doesn't take care if it was called from A or B.
So for example, we had patched string.Join method. And the we call from A or B, where A or B, is the full callstack of this method.
So first, we need to assign a ID to this call, and we need to create a Tree-based structure (which is hard to serialize later), from here (https://stackoverflow.com/a/36649069/3286975):
public class TreeModel : Tree<TreeModel>
{
public int ID { get; set; }
public TreeModel() { }
public TreeModel(TreeModel parent) : base(parent) { }
}
public class Tree<T> where T : Tree<T>
{
protected Tree() : this(null) { }
protected Tree(T parent)
{
Parent=parent;
Children=new List<T>();
if(parent!=null)
{
parent.Children.Add(this as T);
}
}
public T Parent { get; set; }
public List<T> Children { get; set; }
public bool IsRoot { get { return Parent==null; } }
public T Root { get { return IsRoot?this as T:Parent.Root; } }
public T RecursiveFind(Predicate<T> check)
{
if(check(this as T)) return this as T;
foreach(var item in Children)
{
var result=item.RecursiveFind(check);
if(result!=null)
{
return result;
}
}
return null;
}
}
Now, the thing is that we need to fill the Tree as long as we iterate all the method and instructions got from Harmony. Forget about Harmony for a second, I will explain only two facts about it.
The lib allows you first to get all patched methods through IEnumerable<MethodBase> TargetMethods() so, you have the Assembly X passed through reflection and filtered all methods that are allowed to be patched (some of them broke Unity, so I decided to skip methods from UnityEngine., UnityEditor. and System.* namespaces).
And we have also the ReadMethodBody method (https://harmony.pardeike.net/api/HarmonyLib.PatchProcessor.html#HarmonyLib_PatchProcessor_ReadMethodBody_System_Reflection_MethodBase_) from a given MethodBase it returns all IL stack instructions.
So we can start to iterate over and over in order to get all instructions and fill the entire tree. This is what I wrote last night:
internal static class BenchmarkEnumerator
{
internal static Dictionary<MethodBase, int> Mappings { get; } = new Dictionary<MethodBase, int>();
internal static Dictionary<int, TreeModel> TreeIDs { get; } = new Dictionary<int, TreeModel>();
internal static Dictionary<MethodBase, BenchmarkTreeModel> TreeMappings { get; } = new Dictionary<MethodBase, BenchmarkTreeModel>();
private static HashSet<int> IDUsed { get; } = new HashSet<int>();
public static int GetID(this MethodBase method)
{
return GetID(method, out _);
}
public static int GetID(this MethodBase method, out bool contains)
{
// A > X = X1
// B > X = X2
if (!Mappings.ContainsKey(method))
{
var id = Mappings.Count;
Mappings.Add(method, Mappings.Count);
IDUsed.Add(id);
contains = false;
return id;
}
contains = true;
return Mappings[method];
}
public static int GetFreeID()
{
int id;
Random rnd = new Random();
do
{
id = rnd.Next();
} while (IDUsed.Contains(id));
IDUsed.Add(id);
return id;
}
public static BenchmarkCall GetCall(int id)
{
return TreeIDs[id]?.Call;
}
public static BenchmarkCall GetCall(this MethodBase method)
{
return TreeIDs[Mappings[method]]?.Call;
}
}
The BenchmarkEnumerator class allow us to differentiate between A or B, but it doesn't care about the full hierarchy, only from the parent MethodBase itself, so I need to write something complex to take in care of the full call stack, which I said I have a problem to understand.
Then we have the TargetMethods:
private static IEnumerable<MethodBase> TargetMethods()
{
Model = new BenchmarkTreeModel();
var sw = Stopwatch.StartNew();
//int i = 0;
return Filter.GetTargetMethods(method =>
{
try
{
var instructions = PatchProcessor.ReadMethodBody(method);
var i = method.GetID(out var contains);
var tree = new TreeModel
{
ID = i
};
if (contains)
{
//var lastId = i;
i = GetFreeID();
tree.ID = i;
tree.FillMethodName($"{method.GetMethodSignature()}_{i}"); // TODO: Check this
tree.Parent = null;
tree.Children = TreeMappings[method].Forest.First().Children; // ??
//DictionaryHelper.AddOrAppend(TreeMappings, method, tree);
TreeMappings[method].Forest.Add(tree);
TreeIDs.Add(i, tree);
Model.Forest.Add(tree);
// UNIT TESTING: All contained methods at this point will have a parent.
// string.Join is being added as a method by a instruction, so when we try to patch it, it will have already a reference on the dictionary
// Here, we check if the method was already added by a instruction CALL
// Logic: If the method is already contained by the mapping dictionary
// then, we will exit adding a new that will have the same childs but a new ID
return false;
}
TreeIDs.Add(i, tree);
tree.FillMethodName($"{method.GetMethodSignature()}_{i}"); // TODO: Check this
foreach (var pair in instructions)
{
var opcode = pair.Key;
if (opcode != OpCodes.Call || opcode != OpCodes.Callvirt) continue;
var childMethod = (MethodBase)pair.Value;
var id = childMethod.GetID(out var _contains);
var subTree = new TreeModel(tree)
{
ID = id
};
if (_contains)
{
id = GetFreeID();
subTree.ID = id;
subTree.FillMethodName($"{childMethod.GetMethodSignature()}_{id}"); // TODO: Check this
subTree.Parent = TreeIDs[i];
subTree.Children = TreeMappings[childMethod].Forest.First().Children;
TreeIDs.Add(id, subTree);
continue;
}
TreeIDs.Add(id, subTree);
subTree.FillMethodName($"{childMethod.GetMethodSignature()}_{id}");
tree.Children.Add(subTree);
TreeMappings.Add(childMethod, new BenchmarkTreeModel());
TreeMappings[childMethod].Forest.Add(subTree);
}
TreeMappings.Add(method, new BenchmarkTreeModel());
TreeMappings[method].Forest.Add(tree);
Model.Forest.Add(tree);
return true;
//var treeModel = new TreeModel();
}
catch (Exception ex)
{
//Debug.LogException(new Exception(method.GetMethodSignature(), ex));
return false;
}
}, sw);
//return methods;
}
The GetMethodSignature is something like:
public static string GetMethodSignature(this MethodBase method)
{
if (method == null) return null;
return method.DeclaringType == null ? method.Name : $"{method.DeclaringType.FullName}.{method.Name}";
}
I think I'll replace it with the MethodBase.ToString instead (what do you think?)
Also, we have the BenchmarkCall class which allow us to take in care how many times the call was done and how many time it has spent at all:
[Serializable]
public class BenchmarkCall
{
public string Method { get; set; }
public double SpentMilliseconds { get; set; }
public long SpentTicks { get; set; }
public double MinSpentMs { get; set; } = double.MaxValue;
public double MaxSpentMs { get; set; } = double.MinValue;
public long MinSpentTicks { get; set; } = long.MaxValue;
public long MaxSpentTicks { get; set; } = long.MinValue;
public double AvgMs => SpentMilliseconds / TimesCalled;
public double AvgTicks => SpentTicks / (double)TimesCalled;
public BenchmarkCall()
{
}
public BenchmarkCall(MethodBase method)
{
Method = method.GetMethodSignature();
}
public override string ToString()
{
if (TimesCalled > 0)
return "BenchmarkCall{\n" +
$"Ticks[SpentTicks={SpentTicks},MinTicks={MinSpentTicks},MaxTicks={MaxSpentTicks},AvgTicks={AvgTicks:F2}]\n" +
$"Ms[SpentMs={SpentMilliseconds:F2},MinMs={MinSpentMs:F2},MaxMs={MaxSpentMs:F2},AvgMs={AvgMs:F2}]\n" +
"}";
return "BenchmarkCall{}";
}
}
}
So I think that my next movement will be to differentiate between X method being called from A or B (Xa or Xb) taking care of the full hierarchy (which I'm not sure how to do) instead of the parent method that calls it, maybe the code I wrote has some to do it with it, but I'm not sure (last night I was so tired, so I didn't code it taking care those facts), build up a list of method signatures with different IDs, and then fill up the tree, ID 1 is Xa and ID 2 is Xb (where I have problems also filling up the tree).
Also I'll need to use the Transpiler in order to alter all code instructions, so if a method has:
void method() {
X1();
X2();
}
We will need to add 2 methods (like prefix/postfix) to measure each instruction call:
void method() {
Start(1);
X1();
End(1);
Start(2);
X2();
End(2);
}
This will be a hard task, but I hope somebody could guide me with this out.
Let us suppose we have a class like below :-
class DoubleLinkedListNode
{
public int Value { get; set; }
public DoubleLinkedListNode(int value)
{
Value = value;
}
public DoubleLinkedListNode next = null;
public DoubleLinkedListNode prev = null;
}
And then we create a dictionary as given below :-
IDictionary<int, DoubleLinkedListNode> dict = new Dictionary<int, DoubleLinkedListNode>();
The key of the dictionary will hold the Value of the DoubleLinkedListNode that it contains like this :-
DoubleLinkedListNode newNode = new DoubleLinkedListNode(value);
dict.Add(newNode.Value, newNode );
Let us also create a function which takes the type of the value of the dictionary as input and we make that value null inside the body of the function as shown below :-
private void RemoveNode(DoubleLinkedListNode nodeToBeRemoved)
{
if(nodeToBeRemoved != null)
{
//Do Something
nodeToBeRemoved = null;
}
}
and we call the function like this :-
RemoveNode(dict[someValue]);
Let us create another function in which we make the value null explicitly as shown below :-
private void RemoveNodeAnother(DoubleLinkedListNode nodeToBeRemoved)
{
if(nodeToBeRemoved != null)
{
//Do Something
dict[nodeToBeRemoved.Value] = null;
}
}
And then we call the function like this :-
RemoveNodeAnother(dict[someValue]);
What is the difference between the above two functions ?
Why I am asking is this I was doing this question on Leetcode. The solution that I wrote is as follows :-
public class FirstUnique
{
private class DoubleLinkedListNode
{
public int Value { get; set; }
public DoubleLinkedListNode(int value)
{
Value = value;
}
public DoubleLinkedListNode next = null;
public DoubleLinkedListNode prev = null;
}
DoubleLinkedListNode dummyHeadNode = new DoubleLinkedListNode(-1);
DoubleLinkedListNode dummyTailNode = new DoubleLinkedListNode(-1);
IDictionary<int, DoubleLinkedListNode> dict = new Dictionary<int, DoubleLinkedListNode>();
public FirstUnique(int[] nums)
{
InitialiseDummyHeadAndTailNodes();
foreach(int i in nums)
{
Add(i);
}
}
public int ShowFirstUnique()
{
return dummyHeadNode.next.Value;
}
public void Add(int value)
{
if (dict.ContainsKey(value))
{
RemoveNode(dict[value]);
}
else
{
DoubleLinkedListNode newNode = new DoubleLinkedListNode(value);
AddNode(newNode);
}
}
private void InitialiseDummyHeadAndTailNodes()
{
dummyHeadNode.next = dummyTailNode;
dummyTailNode.prev = dummyHeadNode;
}
private void RemoveNode(DoubleLinkedListNode nodeToBeRemoved)
{
if(nodeToBeRemoved != null)
{
nodeToBeRemoved.prev.next = nodeToBeRemoved.next;
nodeToBeRemoved.next.prev = nodeToBeRemoved.prev;
// If I write nodeToBeRemoved = null, the solution won't pass.
// But if I write dict[nodeToBeRemoved.Value] = null, the solution is accepted.
dict[nodeToBeRemoved.Value] = null;
}
}
private void AddNode(DoubleLinkedListNode nodeToBeAdded)
{
//Update the pointers.
nodeToBeAdded.prev = dummyTailNode.prev;
nodeToBeAdded.prev.next = nodeToBeAdded;
nodeToBeAdded.next = dummyTailNode;
dummyTailNode.prev = nodeToBeAdded;
//Add the node to the dictionary.
dict.Add(nodeToBeAdded.Value, nodeToBeAdded);
}
}
I have made the comments where the anomaly lies. What could be the reason for this behavior ?
There is only one way to "set dictionary value to null" -
dictionary[key] = null;
indeed, if key is not there you need to add it first... Which leads to the way to set value to null -
if (dictionary.ContainsKey(key))
dictionary[key] = null;
else
dictionary.Add(key, null);
Note that setting value to null has zero impact on what was stored there previously.
I'd like to know an idiom in C#. I write code related Remote Proxy.
public Task SetIndexAsync(int index)
{
var state = this.StateManager.TryGetStateAsync<ActorState>("MyState").GetAwaiter().GetResult().Value;
if (state == null)
{
state = new ActorState() { Temperature = 0 };
}
state.Index = index;
this.StateManager.SetStateAsync<ActorState>("MyState", state);
return Task.FromResult(true);
}
This is not cool. :(
I try to write like this. However, it is still not cool.
private ActorState StateProxy
{
get
{
return this.StateManager.TryGetStateAsync<ActorState>("MyState").GetAwaiter().GetResult().Value;
}
set
{
this.StateManager.AddOrUpdateStateAsync<ActorState>("MyState", value, (k, v) => value)
}
}
public Task SetIndexAsync(int index)
{
Func<ActorState, int, ActorState> addIndex = (state, idx) => { state.Index = idx; return state; };
addIndex(StateProxy, index);
return Task.FromResult(true);
}
If I could write one-liner which returns instance with modifying the attribute,
it might be better. Or any ideas for a cool solution for this?
Finally, I decide to go like this. I recall the design of ActiveRecord.
internal sealed class ActorState
{
[DataMember]
public List<string> PartitionNames { get; set; }
[DataMember]
public Dictionary<string, DateTime> PartitionLeases { get; set; }
private IActorStateManager stateManager;
internal static ActorState GetState(IActorStateManager stateManager)
{
var state = stateManager.GetStateAsync<ActorState>("MyState").GetAwaiter().GetResult();
state.stateManager = stateManager;
return state;
}
internal void Save()
{
stateManager.AddOrUpdateStateAsync<ActorState>("MySate", this, (k,v) => this ).GetAwaiter();
}
}
Usage:
var stateProxy = ActorState.GetState(this.StateManager);
List<string> keys = stateProxy.PartitionLeases.Keys.ToList();
foreach(string key in keys)
{
if (DateTime.Now - stateProxy.PartitionLeases[key] >= TimeSpan.FromSeconds(60))
stateProxy.PartitionLeases.Remove(key);
}
stateProxy.Save();
Return the value only when it is available. if I use a condition to check the null condition it is throwing a exception. "saying not all code paths return a value"
internal PinMessage()
{
obj.PinsAvailable.ObserveOn(SynchronizationContext.Current).Subscribe(HandlePinsAvailable);
}
private void HandlePinsAvailable(byte[] pinBytes)
{
pinmesssage = Encoding.ASCII.GetString(pinBytes);
}
internal string GetPinMessage(string AccoutNumber)
{
string pinstring = string.Empty;
obj.SendPinRequest(AccoutNumber);
pinstring = pinmesssage;
return pinstring;
}
private string _pinMessage;
public string pinmesssage
{
get//Not all Code paths return a value
{
if (_pinMessage != null)
return _pinMessage;
}
set { _pinMessage = value; }
}
You are getting this compile error because you don't return anything in the case where _pinMesSafe is null. You need to return something from your Access or in the case when that is true, or throw an exception.
private string _pinMessafe;
public string pinmesssage
{
get {
if (_pinMessafe != null)
return _pinMessafe;
}
set { _pinMessafe = value; }
}
You have to return something when it's being called, you can't just put a method call on hold.
What you could do is force a check yourself:
private string _pinMessafe;
public string pinmesssage
{
get {
return _pinMessafe ?? GetMessage()
}
set { _pinMessafe = value; }
}
In this scenario, GetMessage() would have to take care of returning the message. It's hard to give a more detailed answer with the information you've provided.
You should edit your code to make it more readable (this includes the english spelling errors) and add info if needed.
This is not the "best" practice, but will work and let your consumer wait until the producer has written the variable.
private string _pinMessafe;
object locker = new object();
public string pinmesssage
{
get
{
string x = null;
while(x == null) {
lock(locker) { x = _pinMessafe ; }
Thread.Sleep(1);
}
return x;
}
set { lock(locker) { _pinMessafe = value; } }
}
Actually I come up with the following implementation
bool DoesNamedDataSlotsExist(string name)
{
try
{
Thread.AllocateNamedDataSlot(name);
}
catch
{
return true;
}
return false;
}
The obvious problem here: If some code calls DoesNamedDataSlotExist() twice, it will first generate false then true (which could be optimized if i would use Thread.FreeNamedDataSlot() ...)
But is there any better way?
EDIT
source of GetNamedDataSlot
public LocalDataStoreSlot GetNamedDataSlot(string name)
{
LocalDataStoreSlot slot2;
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
Monitor.ReliableEnter(this, ref tookLock);
LocalDataStoreSlot slot = (LocalDataStoreSlot) this.m_KeyToSlotMap[name];
if (slot == null)
{
return this.AllocateNamedDataSlot(name);
}
slot2 = slot;
}
finally
{
if (tookLock)
{
Monitor.Exit(this);
}
}
return slot2;
}
Somehow I would need to access this.m_KeyToSlotMap...
You can duplicate the behavior you observe in GetNamedDataSlot source.
You can introduce special entity, say Thread local storage adapter, that will maintain the dictionary of already allocated data slots. All allocations of data slots should be made via this entity.
Here's what I mean
internal static class TLSAdapter
{
static Dictionary<string, LocalDataStoreSlot> tlsSlots = new Dictionary<string, LocalDataStoreSlot>();
public static bool DoesNamedDataSlotsExist(string name)
{
lock(tlsSlots)
{
return tlsSlots.ContainsKey(name);
}
}
public static LocalDataStoreSlot AllocateNamedDataSlot (string name)
{
lock(tlsSlots)
{
LocalDataStoreSlot slot = null;
if ( tlsSlots.TryGetValue(name, out slot) )
return slot;
slot = Thread.GetNamedDataSlot(name);
tlsSlots[name] = slot;
return slot;
}
}
}