Service Fabric reliable state and F# default GetHashCode issue - f#

I having an issue when trying to update a SF stateful service after updating a child object of the service state. The upgrade fails to pass the 1st upgrade domain with a 'package activation' error. Digging around in the event viewer on the offending node gives the below exception:
Errormsg=TStore.OnApplyAddAsync: Unexpected exception System.NullReferenceException: Object reference not set to an instance of an object.
at xxx.DataChildObject.GetHashCode(IEqualityComparer comp)
at xxx.Data.GetHashCode(IEqualityComparer comp)
at xxx.Data.GetHashCode() in C:\Users\xxx\Source\Repos\xxx\xxx\xxx.Core\Domain.fs:line 17
at System.Fabric.Store.TStore`5.OnApplyAdd(TransactionBase txn, MetadataOperationData metadataOperationData, RedoUndoOperationData operationRedoUndo, Boolean isIdempotent, String applyType) Assert=System.Exception: at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
The change to the 'DataChildObject' was to add a new field that is a tuple of 2 doubles.
I understand that F# is automatically generating equality methods and these must be triggered during SF state and that due to datacontact serialisation these are null during the GetHashCode check.
I don't understand exactly when this check is being performed or why though?
As a test i tried overriding the GetHasCode method on my DataChildObject, but this didn't change the error i get when trying to upgrade my service.
[<DataContract>]
type DataChildObject =
class
[<DataMember(IsRequired=false,Name="Value1")>] val mutable Value1 : float * float
[<DataMember(IsRequired=false,Name="Value2")>] val mutable Value2 : float * float
[<DataMember(IsRequired=false,Name="NewValue")>] val mutable NewValue : float * float
new (v1,v2) = {Value1=v1;Value2=v2;NewValue=1.0,1.0}
override this.GetHashCode() =
let value1 = if (box this.Value1 = null) then 1 else this.Value1.GetHashCode()
let value2 = if (box this.Value2 = null) then 1 else this.Value2.GetHashCode()
let newValue = if (box this.NewValue = null) then 1 else (this.NewValue).GetHashCode()
value1+value2+newValue
end
I expect these domain objects to change more in the near future so any help in understanding exact how to get past or avoid this issue is helpful.
Thanks

Related

Is it atomic operation when exchange std::atomic with itself?

Will following code be executed atomically?
const int oldId = id.exchange((id.load()+1) % maxId);
Where id is std::atomic<int>, and maxId is some integer value.
I searched google and stackoverflow for std::atomic modulo increment. And I found some topics but I can't find clear answer how to do that properly.
In my case even better would be to use:
const int newId = id.exchange((++id) % maxId);
But I am still not sure if it will be executed atomically.
No, this is not atomic, because the load() and the exchange() are separate operations, and nothing is preventing id from getting updated after the load, but before the exchange. In that case your exchange would write a value that has been calculated based on a stale input, so you end up with a missed update.
You can implement a modulo increment using a simple compare_exchange loop:
int val = id.load();
int newVal = (val + 1) % maxId;
while (!id.compare_exchange_weak(val, newVal) {
newVal = (val + 1) % maxId;
}
If the compare_exchange fails it performs a reload and populates val with the updated value. So we can re-calculate newVal and try again.
Edit:
The whole point of the compare-exchange-loop is to handle the case that between the load and the compare-exchange somebody might change id. The idea is to:
load the current value of id
calculate the new value
update id with our own value if and only if the value currently stored in id is the same one as we read in 1. If this is the case we are done, otherwise we restart at 1.
compare_exchange is allows us to perform the comparison and the conditional update in one atomic operation. The first argument to compare_exchange is the expected value (the one we use in our comparison). This value is passed by reference. So when the comparison fails, compare_exchange automatically reloads the current value and updates the provided variable (in our case val).
And since Peter Cordes pointed out correctly that this can be done in a do-while loop to avoid the code duplication, here it is:
int val = id.load();
int newVal;
do {
newVal = (val + 1) % maxId;
} while (!id.compare_exchange_weak(val, newVal);

Instancing Nested Object (Dart)

On trying to assign values to Nested Object Properties,Dart treats the Nested Object(class OperandRange) as null.
Default values have been assigned to the Nested Object Properties but the issue exists.
In the case below Nested Object Class OperandRange should be assigned minimum and maximum values but dart considers it to the Null.
How to resolve this?
Code
import 'dart:io';
//Nested Object Class
class OperandRange{
double _minValue = 0;
double _maxValue = 10;
OperandRange(this._minValue , this._maxValue);
double get minValue => _minValue;
double get maxValue => _maxValue;
set minValue(double _val){
_minValue = (_val) ;
}
set maxValue(double _val){
_maxValue = (_val) ;
}
}
class OperationData{
List<OperandRange> operandList = [];//Nested Object
List<String> operatorList = [] ;
OperationData({this.operandList, this.operatorList});
}
void main(){
int _operationCount = 2;
OperationData _operation = OperationData();
for(int _index = 0 ; _index < _operationCount ; _index++) {
stdout.write(" Operation $_index - Name(string): ");
_operation.operatorList[_index] = stdin.readLineSync();
//Null Object
stdout.write(" Operand $_index - Minimum Value (double) : ");
_operation.operandList[_index]._minValue =
double.parse(stdin.readLineSync());
stdout.write(" Operand $_index - Maximum Value (double): ");
_operation.operandList[_index]._maxValue =
double.parse(stdin.readLineSync());
}
}
Error
Operation 0 - Name(string): Add
Unhandled exception:
NoSuchMethodError: The method '[]=' was called on null.
Receiver: null
Tried calling: []=(0, "Add")
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 main (1.dart:41:28)
#2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
Process finished with exit code 255
Here is what's happening.
You initialize operandList with a nested list. But this never has any effect because you also initialize it in OperationData constructor. Once you mention it in constructor arguments, it will either be set to a value you pass to constructor, or set to null if you do not pass this argument to constructor.
For your purpose you may remove constructor altogether as you never pass anything to it. Then your [] defaults will stand.
Otherwise, if in some cases you need to initialize it with a custom list, you may do it like this:
class OperationData{
List<OperandRange> operandList;
List<String> operatorList;
OperationData({
List<OperandRange> operandList,
List<String>operatorList,
}) :
this.operandList = operandList ?? <OperandList>[],
this.operatorList = operatorList ?? <String>[]
;
}
The same goes for your OperandRange class. 0 and 10 defaults will never be used as the constructor requires explicit values. By the way, I do not see OperandRange creation at all. The list stays empty. You will catch a next error when trying to access an index out of bounds when you fix the first error.
Also you should upgrade to Dart 2.12 if possible. It introduced null-safety that would show you this error at compile time.

Incomplete structured construct

i am new with f# , will be great if some 1 can help , nearly half a day gone solving this problem Thank you
module Certificate =
type T = {
Id: int
IsECert: bool
IsPrintCert: bool
CertifiedBy: string
Categories: Category.T list
}
let createPending now toZonedDateTime toBeCertifiedByName (job: Models.Job.T) (certificateType: Models.CertificateType.T) (pendingCertificate: Models.PendingCertificate.T) visualization (categories: Category.T list) =
let forCompletion = Models.PendingCertificate.getCertificateForCompletion pendingCertificate
{
Id = forCompletion.Id |> CertificateId.toInt
IsECert = Models.PendingCertificate.isECertificate pendingCertificate
IsPrintCert = Models.PendingCertificate.isPrintCertificate pendingCertificate
CertifiedBy = toBeCertifiedByName
Categories = categories}
i am getting an error in "Incomplete structured construct at or before this point"
Your formatting is all off. I will assume here that this is just a result of posting to StackOverflow, and your actual code is well indented.
The error comes from the definition of createPending: this function does not have a result. All its body consists of defining a forCompletion value, but there is nothing after it. Here's a simpler example that has the same problem:
let f x =
let y = 5
This function will produce the same error, because it also doesn't have a result. In F#, every function has to return something. The body cannot contain only definitions of helper functions or values. For example, I could fix my broken function above like this:
let f x =
let y = 5
x + y
This function first defines a helper value y, then adds it to its argument x, and returns the result.
> f 2
> 7
>
> f 0
> 5
How exactly you need to fix your function depends on what exactly you want it to mean. I can't help you here, because you haven't provided that information.

Error adding containts to solver in z3

assign wfwe = wb_acc & (adr_i == 2'b10) & ack_o & we_i;
For the above assign statement which is in verilog, i getting error while implememting it in z3
My code:
BitVecExpr[] wfwe = new BitVecExpr[1];
BitVecExpr[] wb_acc = new BitVecExpr[1];
BitVecExpr[] adr_i = new BitVecExpr[1];
BitVecExpr[] ack_o = new BitVecExpr[1];
BitVecExpr[] we_i = new BitVecExpr[1];
wfwe[0] = ctx.mkBVConst("wfwe",1);
wb_acc[0] = ctx.mkBVConst("wb_acc",1);
adr_i[0] = ctx.mkBVConst("adr_i",2);
ack_o[0] = ctx.mkBVConst("ack_o",1);
we_i[0] = ctx.mkBVConst("we_i",1);
Solver s = ctx.mkSolver();
s.add(ctx.mkBVAND(wb_acc[0],ctx.mkEq(adr_i[0],ctx.mkNumeral("2",2)),ack_o[0],we_i[0]));
I am getting error in above add statement:
error: method mkBVAND in class Context cannot be applied to given types;
required: BitVecExpr,BitVecExpr
found: BitVecExpr,BoolExpr
Which is true. Can anyone suggest me workaround. Am i implementing it incorrectly please let me know.
This error is reported because the second argument of mkBVAND is a Boolean expression (ctx.mkEq ...). Note that Booleans and BitVectors of size 1 are not the same thing, and they will not be converted automatically. The easiest way to convert between them is an if-then-else the selects the right values.
These are the problems with this example:
1) ctx.mkNumeral("2",2) is incorrect. I guess the intention was to create a bv-numeral of 2 bits with value 2; the easiest way to achieve that is ctx.mkBV(2, 2)
2) The 2nd argument of mkBVAND needs to be converted from Bool to BitVector, e.g., like so:
BoolExpr c = ctx.mkEq(adr_i[0], ctx.mkBV(2, 2));
BitVecExpr e = (BitVecExpr) ctx.mkITE(c, ctx.mkBV(1, 1), ctx.mkBV(0, 1));
e being the result.
3) ctx.mkBVAND takes exactly 2 arguments, no more and no less. Thus, the BVAND expression needs to be rewritten, e.g., like so:
ctx.mkBVAND(ctx.mkBVAND(wb_acc[0], e), ctx.mkBVAND(ack_o[0], we_i[0])))
4) The result needs to be converted to a Boolean expression again, e.g.
ctx.mkEq(q, ctx.mkBV(1, 1))
where q is the result of the BVAND.

Weird result comparing property values using reflection

Can someone explain why this is occurring? The code below was executed in the immediate window in vs2008. The prop is an Int32 property (id column) on an object created by the entity framework.
The objects entity and defaultEntity were created using Activator.CreateInstance();
Convert.ChangeType(prop.GetValue(entity, null), prop.PropertyType)
0
Convert.ChangeType(prop.GetValue(defaultEntity, null), prop.PropertyType)
0
Convert.ChangeType(prop.GetValue(entity, null), prop.PropertyType) == Convert.ChangeType(prop.GetValue(defaultEntity, null), prop.PropertyType)
false
I assume you're wondering why the third line prints false. If you want to know why the first two lines are printing 0, you'll have to post more code and tell us what you actually expected.
Convert.ChangeType returns object. Therefore when the property type is actually Int32 it will return a boxed integer.
Your final line is comparing the references of two boxed values. Effectively you're doing:
object x = 0;
object y = 0;
Console.WriteLine (x == y); // Prints False
You can use Equals instead - and the static object.Equals method handily copes with null references, should that be an issue:
object x = 0;
object y = 0;
Console.WriteLine (object.Equals(x, y)); // Prints True

Resources