State Machine Guards and Class Constraints - mdriven

QUESTION:
WHEN DO CLASS CONSTRAINTS BECOME PART OF STATE MACHINE TRANSITION GUARDS?
This is a demo application:
In the model have a state machine transition with a guard
"not self.Guard23 and (self.State22Count>3)"
In the model the class has a Constraint
"(self.State22Count>6)"
At runtime the guard is seen to be
Guard=(not self.Guard23 and (self.State22Count>3)) and (self.State22Count>6)
So it would seems that the class constraint is included in the guard for this transition.
But it is not included in other state transitions guards.
IObjectStateMachine sm = obj.StateMachine;
foreach (Eco.UmlRt.IRegion region in obj.StateMachine.StateMachine.Regions)
{
string guard;
string triggerName;
ITransitionCollection TransCoolection = sm.GetTransitions(region);
foreach (Eco.UmlRt.Impl.TransitionImpl Trans in TransCoolection )
{
guard = Trans.Guard.Body;
triggerName = Trans.Trigger.Name;
string msg = $"Guard={guard} trigger={triggerName} ";
Console.WriteLine(msg);
}
DEBUG Output below.
TransCoolection
Trans#=0 Guard= trigger=TriggerSelf
Trans#=1 Guard=(not self.Guard23 and
(self.State22Count>3)) and (self.State22Count>6) trigger=Trigger23
Trans#=2 Guard=self.Guard23 trigger=Trigger23
Triggers
trigger: TriggerSelf CanTrigger=True
trigger: Trigger23 CanTrigger=True
Invoke Triggers
TriggerSelf trigger: Invoked
Trigger23 trigger: Invoked

Related

EF Core - Change Tracking child records

I'm creating a change log on my records and ChangeTracking only reads records from the main class.
I've already added slow loading and the child classes are being loaded inside my EntityEntry, but I can't capture them through entry.Properties
My class
private void OnBeforeSaveChanges()
{
ChangeTracker.DetectChanges();
var auditEntries = new List<AuditEntry>();
foreach (var entry in ChangeTracker.Entries())
{
if (entry.Entity is AuditLog || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged)
continue;
var auditEntry = new AuditEntry(entry)
{
TableName = entry.Entity.GetType().Name,
UserId = _aplicationUser.GetId
};
auditEntries.Add(auditEntry);
foreach (var property in entry.Properties)
{
string propertyName = property.Metadata.Name;
if (property.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[propertyName] = property.CurrentValue;
continue;
}
switch (entry.State)
{
case EntityState.Added:
auditEntry.AuditType = AuditType.Create;
auditEntry.NewValues[propertyName] = property.CurrentValue;
break;
case EntityState.Deleted:
auditEntry.AuditType = AuditType.Delete;
auditEntry.OldValues[propertyName] = property.OriginalValue;
break;
case EntityState.Modified:
if (property.IsModified)
{
auditEntry.ChangedColumns.Add(propertyName);
auditEntry.AuditType = AuditType.Update;
auditEntry.OldValues[propertyName] = property.OriginalValue;
auditEntry.NewValues[propertyName] = property.CurrentValue;
}
break;
}
}
}
foreach (var auditEntry in auditEntries)
{
var auditDto = auditEntry.ToAudit();
AuditLogs.Add(new AuditLog(auditDto.Id, auditDto.UserId, auditDto.Type, auditDto.TableName, auditDto.DateTime,
auditDto.OldValues, auditDto.NewValues, auditDto.AffectedColumns, auditDto.PrimaryKey));
}
}
The change tracker reports on a per-entity basis. If you have a Parent entity and a Child collection beneath it and make a change to the parent and one or more children, the parent only shows up in the change tracker because of the changes to the parent's properties. It does not list the properties of all related / child entities. Any modified children would appear in the ChangeTracker as Child entities.
For example:
var parent = context.Parents.Include(x => x.Children).Single(x => x.Id == parentId);
var oldestChild = parent.Children.OrderByDescending(x => x.Age).FirstOrDefault();
parent.SomeValue = newValue;
if (oldestChild != null)
oldestChild.OtherValue = someOtherValue;
context.SaveChanges();
In this case the change tracker would include Parent if, and only if the newValue differed from the existing SomeValue. The change tracker would also include the Child denoted as the oldestChild if such a child actually exists, and the someOtherValue differed from that child's OtherValue. If the Child's value was the only one that actually changed then the Change tracker would not include that child's Parent, only the Child reference. This means you cannot really capture an easy "complete" before and after snapshot of an entire object graph. (Parent and all of it's children before and after, or including the parent when one of it's children happens to change) You can do it, but it will involve piecing the deltas together based on what's in the change tracker.
When it comes to writing audit records I would suggest using a bounded DbContext solely for this purpose that only manages the audit log entities and keeps the entity structure as simple as absolutely possible. This way main app context can intercept and inspect changes without worrying about audit changes, and the audit DbContext avoids this overhead, just performing the raw writes.

Execute gatling scenarios based on a boolean flag

Is it possible in Gatling to execute scenarios based on a boolean flag from properties file
application.conf
config {
isDummyTesting = true,
Test {
baseUrl = "testUrl"
userCount = 1
testUser {
CustomerLoginFeeder = "CustomerLogin.getLogin()"
Navigation = "Navigation.navigation"
}
},
performance {
baseUrl = "testUrl"
userCount = 100
testUser {
CustomerLoginFeeder = "CustomerLogin.getLogin()"
}
}
}
and in my simulation file
var flowToTest = ConfigFactory.load().getObject("config.performance.testUser").toConfig
if (ConfigFactory.load().getBoolean("config.isDummyTesting")) {
var flowToTest = ConfigFactory.load().getObject("config.Test.testUser").toConfig
}
while executing flow, i am running below code
scenario("Customer Login").exec(flowToTest)
and facing error
ERROR : io.gatling.core.structure.ScenarioBuilder
cannot be applied to (com.typesafe.config.Config)
I want if flag is true, it executes two scenarios else the other one.
I think you're making a mistake in trying to have to flow defined in the config, rather than just the flag. You can then load the value of the isDummyTesting flag and have that passed into a session variable. From there, you can use the standard gatling doIf construct to include Navigation.navigation if specified.
so in your simulation file, you can have
private val isDummyTesting = java.lang.Boolean.getBoolean("isDummyTesting")
and then in your scenario
.exec(session => session.set("isDummyTesting", isDummyTesting))
...
.exec(CustomerLogin.getLogin())
.doIf("${isDummyTesting}") {
exec(Navigation.navigation)
}

Test class for trigger

I just wrote this trigger and it seems to be working fine in dev, I need to move it into production, however, the test class I wrote passes the test but does not cover the trigger. Any help would be greatly appreciated. I am a bit green here. I know I should be inserting a contact (the account is a req field) then updating the contact field I just have no earthly clue how to do taht. Thank you
trigger PropOwned on Contact (after update) {
for (Contact c : Trigger.new) {
McLabs2__Ownership__c ownNew = new McLabs2__Ownership__c();
Contact oldContact = Trigger.oldMap.get(c.id);
if (c.One_Prop_Owned__c != oldContact.One_Prop_Owned__c && c.One_Prop_Owned__c != null) {
ownNew.McLabs2__Contact__c = c.id;
ownNew.McLabs2__Property__c = c.One_Prop_Owned__c;
insert ownNew;
}
}
}
This is the test class I wrote.
#isTest
public class TestOwnership {
static testMethod void createOwnership() {
McLabs2__Ownership__c ownNew = new McLabs2__Ownership__c();
ownNew.McLabs2__Contact__c = 'Michael Webb';
ownNew.McLabs2__Property__c = '131 West 33rd Street';
insert ownNew;
}
}
Your test class just creates a McLabs2__Ownership__c object and inserts this object in database. As a result of this trigger on McLabs2__Ownership__c(if exist) will be invoked, but you have to test a trigger on Contact object. Thus you need to insert an account and after that update it because your contact trigger works in after update mode.
So, you need something like that
#isTest
private class TestOwnership {
static testMethod void whenContactUpdatedNewOwnershipIsInserted() {
// create contact, you have to replace 'value1' with appropriate data type
Contact contact = new Contact(name = 'Test Contact', One_Prop_Owned__c = 'value1');
insert contact;
contact.One_Prop_Owned__c = 'value2'; // you have to replace value2 with appropriate data type
update contact;
// in this place you should has only one record of McLabs2__Ownership__c in database, because in test context real data isn't visible
List<McLabs2__Ownership__c> ownerships = [SELECT Id, McLabs2__Contact__c, McLabs2__Property__c FROM McLabs2__Ownership__c];
System.assertEquals(1, ownerships.size());
System.assertEquals(contact.Id, ownerships[0].McLabs2__Contact__c);
System.assertEquals(contact.One_Prop_Owned__c, ownerships[0].McLabs2__Property__c);
}
}
Read the following articles which might be pretty useful for you:
Apex Trigger best practice
SOQL in loop

MongoDB Unknown discriminator value

I've added the code in the answer to this question: Unknown discriminator value 'MyEvent', but it didn't help.
An error occurred while deserializing the Body property of class EventStore.EventMessage: Unknown discriminator value : "Insert event name".
Error only occurs when you try to rehydrate a saved object after program restart.
Running latest MyGet Build
Sample Repository:https://github.com/tonyeung/EventStore-MongoDB
To replicate the issue:
run the program
press c to create a new record
press q to quit
run the program again
but press r to rehydrate
error triggers
If you run the program, press c, press enter to continue, and press r to rehydrate without quitting, the object is rehydrated without a problem. WAT?
using (var eventStore = WireupEventStore())
{
var snapshot = eventStore.Advanced.GetSnapshot(ID, int.MaxValue);
if (snapshot == null)
{
// ERRORS HERE
using (var stream = eventStore.OpenStream(ID, 0, int.MaxValue))
{
var events = from s in stream.CommittedEvents
select s.Body as IEvent;
obj.LoadsFromHistory(events);
}
}
}
github issue: https://github.com/NEventStore/NEventStore/issues/203
I figured it out, since I was using an interface as a marker for my events, I had to change the query from the SO question from
var types = Assembly.GetAssembly(typeof(SimpleCQRS.Event))
.GetTypes()
.Where(type => type.IsSubclassOf(typeof(SimpleCQRS.Event)));
to
var type = typeof(IEvent);
var types = Assembly.GetAssembly(typeof(IEvent))
.GetTypes()
.Where(t => type.IsAssignableFrom(t))
.Where(t => t.IsClass);

IronRuby performance issue while using Variables

Here is code of very simple expression evaluator using IronRuby
public class BasicRubyExpressionEvaluator
{
ScriptEngine engine;
ScriptScope scope;
public Exception LastException
{
get; set;
}
private static readonly Dictionary<string, ScriptSource> parserCache = new Dictionary<string, ScriptSource>();
public BasicRubyExpressionEvaluator()
{
engine = Ruby.CreateEngine();
scope = engine.CreateScope();
}
public object Evaluate(string expression, DataRow context)
{
ScriptSource source;
parserCache.TryGetValue(expression, out source);
if (source == null)
{
source = engine.CreateScriptSourceFromString(expression, SourceCodeKind.SingleStatement);
parserCache.Add(expression, source);
}
var result = source.Execute(scope);
return result;
}
public void SetVariable(string variableName, object value)
{
scope.SetVariable(variableName, value);
}
}
and here is problem.
var evaluator = new BasicRubyExpressionEvaluator();
evaluator.SetVariable("a", 10);
evaluator.SetVariable("b", 1 );
evaluator.Evaluate("a+b+2", null);
vs
var evaluator = new BasicRubyExpressionEvaluator();
evaluator.Evaluate("10+1+2", null);
First Is 25 times slower than second. Any suggestions? String.Replace is not a solution for me.
I do not think the performance you are seeing is due to variable setting; the first execution of IronRuby in a program is always going to be slower than the second, regardless of what you're doing, since most of the compiler isn't loaded in until code is actually run (for startup performance reasons). Please try that example again, maybe running each version of your code in a loop, and you'll see the performance is roughly equivalent; the variable-version does have some overhead of method-dispatch to get the variables, but that should be negligible if you run it enough.
Also, in your hosting code, how come you are holding onto ScriptScopes in a dictionary? I would hold onto CompiledCode (result of engine.CreateScriptSourceFromString(...).Compile()) instead -- as that will help a lot more in repeat runs.
you can of course first build the string something like
evaluator.Evaluate(string.format("a={0}; b={1}; a + b + 2", 10, 1))
Or you can make it a method
if instead of your script you return a method then you should be able to use it like a regular C# Func object.
var script = #"
def self.addition(a, b)
a + b + 2
end
"
engine.ExecuteScript(script);
var = func = scope.GetVariable<Func<object,object,object>>("addition");
func(10,1)
This is probably not a working snippet but it shows the general idea.