mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-06 11:32:59 +00:00
deadlock prevention
This commit is contained in:
parent
f258464063
commit
20fcaba518
@ -43,7 +43,7 @@ namespace Esiur.Data;
|
|||||||
public static class Codec
|
public static class Codec
|
||||||
{
|
{
|
||||||
|
|
||||||
delegate AsyncReply Parser(byte[] data, uint offset, uint length, DistributedConnection connection);
|
delegate AsyncReply Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence);
|
||||||
|
|
||||||
|
|
||||||
static Parser[][] FixedParsers = new Parser[][]
|
static Parser[][] FixedParsers = new Parser[][]
|
||||||
@ -114,7 +114,7 @@ public static class Codec
|
|||||||
/// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end.</param>
|
/// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end.</param>
|
||||||
/// <param name="dataType">DataType, in case the data is not prepended with DataType</param>
|
/// <param name="dataType">DataType, in case the data is not prepended with DataType</param>
|
||||||
/// <returns>Value</returns>
|
/// <returns>Value</returns>
|
||||||
public static (uint, AsyncReply) Parse(byte[] data, uint offset, DistributedConnection connection, TransmissionType? dataType = null)
|
public static (uint, AsyncReply) Parse(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence, TransmissionType? dataType = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint len = 0;
|
uint len = 0;
|
||||||
@ -132,15 +132,15 @@ public static class Codec
|
|||||||
|
|
||||||
if (tt.Class == TransmissionTypeClass.Fixed)
|
if (tt.Class == TransmissionTypeClass.Fixed)
|
||||||
{
|
{
|
||||||
return (len, FixedParsers[tt.Exponent][tt.Index](data, dataType.Value.Offset, (uint)tt.ContentLength, connection));
|
return (len, FixedParsers[tt.Exponent][tt.Index](data, dataType.Value.Offset, (uint)tt.ContentLength, connection, requestSequence));
|
||||||
}
|
}
|
||||||
else if (tt.Class == TransmissionTypeClass.Dynamic)
|
else if (tt.Class == TransmissionTypeClass.Dynamic)
|
||||||
{
|
{
|
||||||
return (len, DynamicParsers[tt.Index](data, dataType.Value.Offset, (uint)tt.ContentLength, connection));
|
return (len, DynamicParsers[tt.Index](data, dataType.Value.Offset, (uint)tt.ContentLength, connection, requestSequence));
|
||||||
}
|
}
|
||||||
else //if (tt.Class == TransmissionTypeClass.Typed)
|
else //if (tt.Class == TransmissionTypeClass.Typed)
|
||||||
{
|
{
|
||||||
return (len, TypedParsers[tt.Index](data, dataType.Value.Offset, (uint)tt.ContentLength, connection));
|
return (len, TypedParsers[tt.Index](data, dataType.Value.Offset, (uint)tt.ContentLength, connection, requestSequence));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,115 +12,115 @@ namespace Esiur.Data;
|
|||||||
|
|
||||||
public static class DataDeserializer
|
public static class DataDeserializer
|
||||||
{
|
{
|
||||||
public static AsyncReply NullParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply NullParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
return new AsyncReply(null);
|
return new AsyncReply(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply BooleanTrueParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply BooleanTrueParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply BooleanFalseParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply BooleanFalseParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
return new AsyncReply<bool>(false);
|
return new AsyncReply<bool>(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply NotModifiedParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply NotModifiedParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
return new AsyncReply<NotModified>(new NotModified());
|
return new AsyncReply<NotModified>(new NotModified());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply ByteParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply ByteParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
return new AsyncReply<byte>(data[offset]);
|
return new AsyncReply<byte>(data[offset]);
|
||||||
}
|
}
|
||||||
public static AsyncReply SByteParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply SByteParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
return new AsyncReply<sbyte>((sbyte)data[offset]);
|
return new AsyncReply<sbyte>((sbyte)data[offset]);
|
||||||
}
|
}
|
||||||
public static unsafe AsyncReply Char16Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply Char16Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<char>(*(char*)ptr);
|
return new AsyncReply<char>(*(char*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply Char8Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply Char8Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
return new AsyncReply<char>((char)data[offset]);
|
return new AsyncReply<char>((char)data[offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static unsafe AsyncReply Int16Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply Int16Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<short>(*(short*)ptr);
|
return new AsyncReply<short>(*(short*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply UInt16Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply UInt16Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<ushort>(*(ushort*)ptr);
|
return new AsyncReply<ushort>(*(ushort*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply Int32Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply Int32Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<int>(*(int*)ptr);
|
return new AsyncReply<int>(*(int*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply UInt32Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply UInt32Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<uint>(*(uint*)ptr);
|
return new AsyncReply<uint>(*(uint*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply Float32Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply Float32Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<float>(*(float*)ptr);
|
return new AsyncReply<float>(*(float*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply Float64Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply Float64Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<double>(*(double*)ptr);
|
return new AsyncReply<double>(*(double*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply Float128Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply Float128Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<decimal>(*(decimal*)ptr);
|
return new AsyncReply<decimal>(*(decimal*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply Int128Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply Int128Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<decimal>(*(decimal*)ptr);
|
return new AsyncReply<decimal>(*(decimal*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static unsafe AsyncReply UInt128Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply UInt128Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<decimal>(*(decimal*)ptr);
|
return new AsyncReply<decimal>(*(decimal*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static unsafe AsyncReply Int64Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply Int64Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<long>(*(long*)ptr);
|
return new AsyncReply<long>(*(long*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply UInt64Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply UInt64Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<ulong>(*(ulong*)ptr);
|
return new AsyncReply<ulong>(*(ulong*)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply DateTimeParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply DateTimeParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return new AsyncReply<DateTime>(new DateTime(*(long*)ptr, DateTimeKind.Utc));
|
return new AsyncReply<DateTime>(new DateTime(*(long*)ptr, DateTimeKind.Utc));
|
||||||
@ -128,14 +128,14 @@ public static class DataDeserializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static unsafe AsyncReply ResourceParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply ResourceParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return connection.Fetch(*(uint*)ptr);
|
return connection.Fetch(*(uint*)ptr, requestSequence);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply LocalResourceParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply LocalResourceParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = &data[offset])
|
fixed (byte* ptr = &data[offset])
|
||||||
return Warehouse.GetById(*(uint*)ptr);
|
return Warehouse.GetById(*(uint*)ptr);
|
||||||
@ -143,17 +143,17 @@ public static class DataDeserializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static unsafe AsyncReply RawDataParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply RawDataParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
return new AsyncReply<byte[]>(data.Clip(offset, length));
|
return new AsyncReply<byte[]>(data.Clip(offset, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply StringParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply StringParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
return new AsyncReply<string>(data.GetString(offset, length));
|
return new AsyncReply<string>(data.GetString(offset, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply RecordParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply RecordParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
|
|
||||||
var reply = new AsyncReply<IRecord>();
|
var reply = new AsyncReply<IRecord>();
|
||||||
@ -165,10 +165,9 @@ public static class DataDeserializer
|
|||||||
|
|
||||||
var template = Warehouse.GetTemplateByClassId((Guid)classId, TemplateType.Record);
|
var template = Warehouse.GetTemplateByClassId((Guid)classId, TemplateType.Record);
|
||||||
|
|
||||||
if (template != null)
|
var initRecord = (TypeTemplate template) =>
|
||||||
{
|
{
|
||||||
//ListParser(data, offset, length, connection)
|
ListParser(data, offset, length, connection, requestSequence).Then(r =>
|
||||||
ListParser(data, offset, length, connection).Then(r =>
|
|
||||||
{
|
{
|
||||||
var ar = (object[])r;
|
var ar = (object[])r;
|
||||||
|
|
||||||
@ -181,7 +180,8 @@ public static class DataDeserializer
|
|||||||
{
|
{
|
||||||
var v = Convert.ChangeType(ar[i], template.Properties[i].PropertyInfo.PropertyType);
|
var v = Convert.ChangeType(ar[i], template.Properties[i].PropertyInfo.PropertyType);
|
||||||
template.Properties[i].PropertyInfo.SetValue(record, v);
|
template.Properties[i].PropertyInfo.SetValue(record, v);
|
||||||
} catch ( Exception ex)
|
}
|
||||||
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine(ex);
|
Console.WriteLine(ex);
|
||||||
}
|
}
|
||||||
@ -199,21 +199,24 @@ public static class DataDeserializer
|
|||||||
reply.Trigger(record);
|
reply.Trigger(record);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (template != null)
|
||||||
|
{
|
||||||
|
initRecord(template);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
connection.GetTemplate((Guid)classId).Then(tmp =>
|
connection.GetTemplate((Guid)classId).Then(tmp =>
|
||||||
{
|
{
|
||||||
ListParser(data, offset, length, connection).Then(r =>
|
ListParser(data, offset, length, connection, requestSequence).Then(r =>
|
||||||
{
|
{
|
||||||
var ar = (object[])r;
|
if (tmp == null)
|
||||||
|
reply.TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.TemplateNotFound,
|
||||||
|
"Template not found for record."));
|
||||||
|
else
|
||||||
|
initRecord(tmp);
|
||||||
|
|
||||||
var record = new Record();
|
|
||||||
|
|
||||||
for (var i = 0; i < tmp.Properties.Length; i++)
|
|
||||||
record.Add(tmp.Properties[i].Name, ar[i]);
|
|
||||||
|
|
||||||
reply.Trigger(record);
|
|
||||||
});
|
});
|
||||||
}).Error(x => reply.TriggerError(x));
|
}).Error(x => reply.TriggerError(x));
|
||||||
}
|
}
|
||||||
@ -221,12 +224,12 @@ public static class DataDeserializer
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply ConstantParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply ConstantParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe AsyncReply EnumParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static unsafe AsyncReply EnumParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
|
|
||||||
var classId = data.GetGuid(offset);
|
var classId = data.GetGuid(offset);
|
||||||
@ -254,13 +257,13 @@ public static class DataDeserializer
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static AsyncReply RecordListParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply RecordListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
var rt = new AsyncBag<IRecord>();
|
var rt = new AsyncBag<IRecord>();
|
||||||
|
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{
|
{
|
||||||
var (cs, reply) = Codec.Parse(data, offset, connection);
|
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
|
||||||
|
|
||||||
rt.Add(reply);
|
rt.Add(reply);
|
||||||
|
|
||||||
@ -278,13 +281,13 @@ public static class DataDeserializer
|
|||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply ResourceListParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply ResourceListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
var rt = new AsyncBag<IResource>();
|
var rt = new AsyncBag<IResource>();
|
||||||
|
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{
|
{
|
||||||
var (cs, reply) = Codec.Parse(data, offset, connection);
|
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
|
||||||
|
|
||||||
rt.Add(reply);
|
rt.Add(reply);
|
||||||
|
|
||||||
@ -303,13 +306,13 @@ public static class DataDeserializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static AsyncBag<object> ListParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncBag<object> ListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
var rt = new AsyncBag<object>();
|
var rt = new AsyncBag<object>();
|
||||||
|
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{
|
{
|
||||||
var (cs, reply) = Codec.Parse(data, offset, connection);
|
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
|
||||||
|
|
||||||
rt.Add(reply);
|
rt.Add(reply);
|
||||||
|
|
||||||
@ -327,7 +330,7 @@ public static class DataDeserializer
|
|||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply TypedMapParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply TypedMapParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
// get key type
|
// get key type
|
||||||
var (keyCs, keyRepType) = RepresentationType.Parse(data, offset);
|
var (keyCs, keyRepType) = RepresentationType.Parse(data, offset);
|
||||||
@ -346,7 +349,7 @@ public static class DataDeserializer
|
|||||||
|
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{
|
{
|
||||||
var (cs, reply) = Codec.Parse(data, offset, connection);
|
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
|
||||||
|
|
||||||
|
|
||||||
results.Add(reply);
|
results.Add(reply);
|
||||||
@ -376,7 +379,7 @@ public static class DataDeserializer
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply TupleParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply TupleParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
var results = new AsyncBag<object>();
|
var results = new AsyncBag<object>();
|
||||||
var rt = new AsyncReply();
|
var rt = new AsyncReply();
|
||||||
@ -396,7 +399,7 @@ public static class DataDeserializer
|
|||||||
|
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{
|
{
|
||||||
var (cs, reply) = Codec.Parse(data, offset, connection);
|
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
|
||||||
|
|
||||||
results.Add(reply);
|
results.Add(reply);
|
||||||
|
|
||||||
@ -435,7 +438,7 @@ public static class DataDeserializer
|
|||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply TypedListParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
public static AsyncReply TypedListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
var rt = new AsyncBag<object>();
|
var rt = new AsyncBag<object>();
|
||||||
|
|
||||||
@ -451,7 +454,7 @@ public static class DataDeserializer
|
|||||||
|
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{
|
{
|
||||||
var (cs, reply) = Codec.Parse(data, offset, connection);
|
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
|
||||||
|
|
||||||
rt.Add(reply);
|
rt.Add(reply);
|
||||||
|
|
||||||
@ -470,12 +473,12 @@ public static class DataDeserializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static AsyncBag<PropertyValue> PropertyValueArrayParser(byte[] data, uint offset, uint length, DistributedConnection connection)//, bool ageIncluded = true)
|
public static AsyncBag<PropertyValue> PropertyValueArrayParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
|
||||||
{
|
{
|
||||||
var rt = new AsyncBag<PropertyValue>();
|
var rt = new AsyncBag<PropertyValue>();
|
||||||
|
|
||||||
|
|
||||||
ListParser(data, offset, length, connection).Then(x =>
|
ListParser(data, offset, length, connection, requestSequence).Then(x =>
|
||||||
{
|
{
|
||||||
var ar = (object[])x;
|
var ar = (object[])x;
|
||||||
var pvs = new List<PropertyValue>();
|
var pvs = new List<PropertyValue>();
|
||||||
@ -491,7 +494,7 @@ public static class DataDeserializer
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (uint, AsyncReply<PropertyValue>) PropertyValueParser(byte[] data, uint offset, DistributedConnection connection)//, bool ageIncluded = true)
|
public static (uint, AsyncReply<PropertyValue>) PropertyValueParser(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
|
||||||
{
|
{
|
||||||
var reply = new AsyncReply<PropertyValue>();
|
var reply = new AsyncReply<PropertyValue>();
|
||||||
|
|
||||||
@ -502,7 +505,7 @@ public static class DataDeserializer
|
|||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
|
|
||||||
var (valueSize, results) = Codec.Parse(data, offset, connection);
|
var (valueSize, results) = Codec.Parse(data, offset, connection, requestSequence);
|
||||||
|
|
||||||
results.Then(value =>
|
results.Then(value =>
|
||||||
{
|
{
|
||||||
@ -512,7 +515,7 @@ public static class DataDeserializer
|
|||||||
return (16 + valueSize, reply);
|
return (16 + valueSize, reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> HistoryParser(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection)
|
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> HistoryParser(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
//var count = (int)toAge - (int)fromAge;
|
//var count = (int)toAge - (int)fromAge;
|
||||||
|
|
||||||
@ -531,7 +534,7 @@ public static class DataDeserializer
|
|||||||
var cs = data.GetUInt32(offset, Endian.Little);
|
var cs = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
var (len, pv) = PropertyValueParser(data, offset, connection);
|
var (len, pv) = PropertyValueParser(data, offset, connection, requestSequence);
|
||||||
|
|
||||||
bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection));
|
bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection));
|
||||||
offset += len;
|
offset += len;
|
||||||
|
@ -274,11 +274,10 @@ public class HTTPServer : NetworkServer<HTTPConnection>, IResource
|
|||||||
|
|
||||||
internal bool Execute(HTTPConnection sender)
|
internal bool Execute(HTTPConnection sender)
|
||||||
{
|
{
|
||||||
|
if (!sender.WSMode)
|
||||||
foreach (var route in routes[sender.Request.Method])
|
foreach (var route in routes[sender.Request.Method])
|
||||||
{
|
|
||||||
if (route.Invoke(sender))
|
if (route.Invoke(sender))
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var resource in filters)
|
foreach (var resource in filters)
|
||||||
|
@ -1225,7 +1225,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
for (var i = 0; i < resources.Keys.Count; i++)
|
for (var i = 0; i < resources.Keys.Count; i++)
|
||||||
{
|
{
|
||||||
var index = resources.Keys.ElementAt(i);
|
var index = resources.Keys.ElementAt(i);
|
||||||
bag.Add(Fetch(index));
|
bag.Add(Fetch(index, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
bag.Seal();
|
bag.Seal();
|
||||||
|
@ -232,7 +232,7 @@ partial class DistributedConnection
|
|||||||
{
|
{
|
||||||
var req = requests.Take(callbackId);
|
var req = requests.Take(callbackId);
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(content, 0, this, transmissionType);
|
var (_, parsed) = Codec.Parse(content, 0, this, null, transmissionType);
|
||||||
parsed.Then((rt) =>
|
parsed.Then((rt) =>
|
||||||
{
|
{
|
||||||
req?.Trigger(rt);
|
req?.Trigger(rt);
|
||||||
@ -256,7 +256,7 @@ partial class DistributedConnection
|
|||||||
if (requests.ContainsKey(callbackId))
|
if (requests.ContainsKey(callbackId))
|
||||||
{
|
{
|
||||||
var req = requests[callbackId];
|
var req = requests[callbackId];
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, dataType);
|
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
|
||||||
parsed.Then((x) =>
|
parsed.Then((x) =>
|
||||||
{
|
{
|
||||||
req.TriggerChunk(x);
|
req.TriggerChunk(x);
|
||||||
@ -282,12 +282,12 @@ partial class DistributedConnection
|
|||||||
void IIPEventPropertyUpdated(uint resourceId, byte index, TransmissionType dataType, byte[] data)
|
void IIPEventPropertyUpdated(uint resourceId, byte index, TransmissionType dataType, byte[] data)
|
||||||
{
|
{
|
||||||
|
|
||||||
Fetch(resourceId).Then(r =>
|
Fetch(resourceId, null).Then(r =>
|
||||||
{
|
{
|
||||||
var item = new AsyncReply<DistributedResourceQueueItem>();
|
var item = new AsyncReply<DistributedResourceQueueItem>();
|
||||||
queue.Add(item);
|
queue.Add(item);
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, dataType);// 0, this);
|
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);// 0, this);
|
||||||
parsed.Then((arguments) =>
|
parsed.Then((arguments) =>
|
||||||
{
|
{
|
||||||
var pt = r.Instance.Template.GetPropertyTemplateByIndex(index);
|
var pt = r.Instance.Template.GetPropertyTemplateByIndex(index);
|
||||||
@ -345,13 +345,13 @@ partial class DistributedConnection
|
|||||||
|
|
||||||
void IIPEventEventOccurred(uint resourceId, byte index, TransmissionType dataType, byte[] data)
|
void IIPEventEventOccurred(uint resourceId, byte index, TransmissionType dataType, byte[] data)
|
||||||
{
|
{
|
||||||
Fetch(resourceId).Then(r =>
|
Fetch(resourceId, null).Then(r =>
|
||||||
{
|
{
|
||||||
// push to the queue to gaurantee serialization
|
// push to the queue to gaurantee serialization
|
||||||
var item = new AsyncReply<DistributedResourceQueueItem>();
|
var item = new AsyncReply<DistributedResourceQueueItem>();
|
||||||
queue.Add(item);
|
queue.Add(item);
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, dataType);//, 0, this);
|
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);//, 0, this);
|
||||||
parsed.Then((arguments) =>
|
parsed.Then((arguments) =>
|
||||||
{
|
{
|
||||||
var et = r.Instance.Template.GetEventTemplateByIndex(index);
|
var et = r.Instance.Template.GetEventTemplateByIndex(index);
|
||||||
@ -406,9 +406,9 @@ partial class DistributedConnection
|
|||||||
|
|
||||||
void IIPEventChildAdded(uint resourceId, uint childId)
|
void IIPEventChildAdded(uint resourceId, uint childId)
|
||||||
{
|
{
|
||||||
Fetch(resourceId).Then(parent =>
|
Fetch(resourceId, null).Then(parent =>
|
||||||
{
|
{
|
||||||
Fetch(childId).Then(child =>
|
Fetch(childId, null).Then(child =>
|
||||||
{
|
{
|
||||||
parent.children.Add(child);
|
parent.children.Add(child);
|
||||||
child.parents.Add(parent);
|
child.parents.Add(parent);
|
||||||
@ -420,9 +420,9 @@ partial class DistributedConnection
|
|||||||
|
|
||||||
void IIPEventChildRemoved(uint resourceId, uint childId)
|
void IIPEventChildRemoved(uint resourceId, uint childId)
|
||||||
{
|
{
|
||||||
Fetch(resourceId).Then(parent =>
|
Fetch(resourceId, null).Then(parent =>
|
||||||
{
|
{
|
||||||
Fetch(childId).Then(child =>
|
Fetch(childId, null).Then(child =>
|
||||||
{
|
{
|
||||||
parent.children.Remove(child);
|
parent.children.Remove(child);
|
||||||
child.parents.Remove(parent);
|
child.parents.Remove(parent);
|
||||||
@ -434,7 +434,7 @@ partial class DistributedConnection
|
|||||||
|
|
||||||
void IIPEventRenamed(uint resourceId, string name)
|
void IIPEventRenamed(uint resourceId, string name)
|
||||||
{
|
{
|
||||||
Fetch(resourceId).Then(resource =>
|
Fetch(resourceId, null).Then(resource =>
|
||||||
{
|
{
|
||||||
resource.Instance.Variables["name"] = name;
|
resource.Instance.Variables["name"] = name;
|
||||||
});
|
});
|
||||||
@ -443,7 +443,7 @@ partial class DistributedConnection
|
|||||||
|
|
||||||
void IIPEventAttributesUpdated(uint resourceId, byte[] attributes)
|
void IIPEventAttributesUpdated(uint resourceId, byte[] attributes)
|
||||||
{
|
{
|
||||||
Fetch(resourceId).Then(resource =>
|
Fetch(resourceId, null).Then(resource =>
|
||||||
{
|
{
|
||||||
var attrs = attributes.GetStringArray(0, (uint)attributes.Length);
|
var attrs = attributes.GetStringArray(0, (uint)attributes.Length);
|
||||||
|
|
||||||
@ -724,19 +724,19 @@ partial class DistributedConnection
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataDeserializer.ListParser(content, offset, cl, this).Then(parameters =>
|
DataDeserializer.ListParser(content, offset, cl, this, null).Then(parameters =>
|
||||||
{
|
{
|
||||||
offset += cl;
|
offset += cl;
|
||||||
cl = content.GetUInt32(offset, Endian.Little);
|
cl = content.GetUInt32(offset, Endian.Little);
|
||||||
|
|
||||||
//Codec.ParseStructure(content, offset, cl, this).Then(attributes =>
|
//Codec.ParseStructure(content, offset, cl, this).Then(attributes =>
|
||||||
DataDeserializer.TypedMapParser(content, offset, cl, this).Then(attributes =>
|
DataDeserializer.TypedMapParser(content, offset, cl, this, null).Then(attributes =>
|
||||||
{
|
{
|
||||||
offset += cl;
|
offset += cl;
|
||||||
cl = (uint)content.Length - offset;
|
cl = (uint)content.Length - offset;
|
||||||
|
|
||||||
//Codec.ParseStructure(content, offset, cl, this).Then(values =>
|
//Codec.ParseStructure(content, offset, cl, this).Then(values =>
|
||||||
DataDeserializer.TypedMapParser(content, offset, cl, this).Then(values =>
|
DataDeserializer.TypedMapParser(content, offset, cl, this, null).Then(values =>
|
||||||
{
|
{
|
||||||
|
|
||||||
#if NETSTANDARD
|
#if NETSTANDARD
|
||||||
@ -1049,7 +1049,7 @@ partial class DistributedConnection
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DataDeserializer.TypedMapParser(attributes, 0, (uint)attributes.Length, this).Then(attrs =>
|
DataDeserializer.TypedMapParser(attributes, 0, (uint)attributes.Length, this, null).Then(attrs =>
|
||||||
{
|
{
|
||||||
if (r.Instance.SetAttributes((Map<string, object>)attrs, clearAttributes))
|
if (r.Instance.SetAttributes((Map<string, object>)attrs, clearAttributes))
|
||||||
SendReply(clearAttributes ? IIPPacket.IIPPacketAction.ClearAllAttributes : IIPPacket.IIPPacketAction.ClearAttributes,
|
SendReply(clearAttributes ? IIPPacket.IIPPacketAction.ClearAllAttributes : IIPPacket.IIPPacketAction.ClearAttributes,
|
||||||
@ -1232,11 +1232,11 @@ partial class DistributedConnection
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(content, 0, this, transmissionType);
|
var (_, parsed) = Codec.Parse(content, 0, this, null, transmissionType);
|
||||||
|
|
||||||
parsed.Then(results =>
|
parsed.Then(results =>
|
||||||
{
|
{
|
||||||
var arguments = (Map<byte, object>)results ;// (object[])results;
|
var arguments = (Map<byte, object>)results;// (object[])results;
|
||||||
|
|
||||||
// un hold the socket to send data immediately
|
// un hold the socket to send data immediately
|
||||||
this.Socket.Unhold();
|
this.Socket.Unhold();
|
||||||
@ -1281,14 +1281,14 @@ partial class DistributedConnection
|
|||||||
{
|
{
|
||||||
if (pis.Last().ParameterType == typeof(DistributedConnection))
|
if (pis.Last().ParameterType == typeof(DistributedConnection))
|
||||||
{
|
{
|
||||||
for(byte i = 0; i< pis.Length - 1; i++)
|
for (byte i = 0; i < pis.Length - 1; i++)
|
||||||
args[i] = arguments.ContainsKey(i) ?
|
args[i] = arguments.ContainsKey(i) ?
|
||||||
DC.CastConvert(arguments[i], pis[i].ParameterType) : Type.Missing;
|
DC.CastConvert(arguments[i], pis[i].ParameterType) : Type.Missing;
|
||||||
args[args.Length - 1] = this;
|
args[args.Length - 1] = this;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (byte i = 0; i < pis.Length ; i++)
|
for (byte i = 0; i < pis.Length; i++)
|
||||||
args[i] = arguments.ContainsKey(i) ?
|
args[i] = arguments.ContainsKey(i) ?
|
||||||
DC.CastConvert(arguments[i], pis[i].ParameterType) : Type.Missing;
|
DC.CastConvert(arguments[i], pis[i].ParameterType) : Type.Missing;
|
||||||
}
|
}
|
||||||
@ -1631,7 +1631,7 @@ partial class DistributedConnection
|
|||||||
var pt = r.Instance.Template.GetPropertyTemplateByIndex(index);
|
var pt = r.Instance.Template.GetPropertyTemplateByIndex(index);
|
||||||
if (pt != null)
|
if (pt != null)
|
||||||
{
|
{
|
||||||
var (_, parsed) = Codec.Parse(content, 0, this, transmissionType);
|
var (_, parsed) = Codec.Parse(content, 0, this, null, transmissionType);
|
||||||
parsed.Then((value) =>
|
parsed.Then((value) =>
|
||||||
{
|
{
|
||||||
if (r is DistributedResource)
|
if (r is DistributedResource)
|
||||||
@ -2000,15 +2000,14 @@ partial class DistributedConnection
|
|||||||
/// <param name="classId">Class GUID</param>
|
/// <param name="classId">Class GUID</param>
|
||||||
/// <param name="id">Resource Id</param>Guid classId
|
/// <param name="id">Resource Id</param>Guid classId
|
||||||
/// <returns>DistributedResource</returns>
|
/// <returns>DistributedResource</returns>
|
||||||
public AsyncReply<DistributedResource> Fetch(uint id)
|
public AsyncReply<DistributedResource> Fetch(uint id, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
var resource = resources[id];
|
var resource = resources[id];
|
||||||
var request = resourceRequests[id];
|
var request = resourceRequests[id];
|
||||||
|
|
||||||
if (request != null)
|
if (request != null)
|
||||||
{
|
{
|
||||||
if (resource != null)
|
if (resource != null && (requestSequence?.Contains(id) ?? false))
|
||||||
// dig for dead locks // or not
|
|
||||||
return new AsyncReply<DistributedResource>(resource);
|
return new AsyncReply<DistributedResource>(resource);
|
||||||
else
|
else
|
||||||
return request;
|
return request;
|
||||||
@ -2022,17 +2021,28 @@ partial class DistributedConnection
|
|||||||
var reply = new AsyncReply<DistributedResource>();
|
var reply = new AsyncReply<DistributedResource>();
|
||||||
resourceRequests.Add(id, reply);
|
resourceRequests.Add(id, reply);
|
||||||
|
|
||||||
|
var newSequence = requestSequence != null ? requestSequence.Concat(new uint[] { id }).ToArray() : new uint[] { id };
|
||||||
|
|
||||||
SendRequest(IIPPacket.IIPPacketAction.AttachResource)
|
SendRequest(IIPPacket.IIPPacketAction.AttachResource)
|
||||||
.AddUInt32(id)
|
.AddUInt32(id)
|
||||||
.Done()
|
.Done()
|
||||||
.Then((rt) =>
|
.Then((rt) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (rt == null)
|
||||||
|
{
|
||||||
|
reply.TriggerError(new AsyncException(ErrorType.Management,
|
||||||
|
(ushort)ExceptionCode.ResourceNotFound, "Null response"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DistributedResource dr;
|
DistributedResource dr;
|
||||||
|
TypeTemplate template = null;
|
||||||
|
Guid classId = (Guid)rt[0];
|
||||||
|
|
||||||
if (resource == null)
|
if (resource == null)
|
||||||
{
|
{
|
||||||
var template = Warehouse.GetTemplateByClassId((Guid)rt[0], TemplateType.Wrapper);
|
template = Warehouse.GetTemplateByClassId(classId, TemplateType.Wrapper);
|
||||||
if (template?.DefinedType != null)
|
if (template?.DefinedType != null)
|
||||||
dr = Activator.CreateInstance(template.DefinedType, this, id, (ulong)rt[1], (string)rt[2]) as DistributedResource;
|
dr = Activator.CreateInstance(template.DefinedType, this, id, (ulong)rt[1], (string)rt[2]) as DistributedResource;
|
||||||
else
|
else
|
||||||
@ -2044,14 +2054,9 @@ partial class DistributedConnection
|
|||||||
var transmissionType = (TransmissionType)rt[3];
|
var transmissionType = (TransmissionType)rt[3];
|
||||||
var content = (byte[])rt[4];
|
var content = (byte[])rt[4];
|
||||||
|
|
||||||
GetTemplate((Guid)rt[0]).Then((tmp) =>
|
var initResource = (DistributedResource ok) =>
|
||||||
{
|
{
|
||||||
// ClassId, ResourceAge, ResourceLink, Content
|
var (_, parsed) = Codec.Parse(content, 0, this, newSequence, transmissionType);
|
||||||
if (resource == null)
|
|
||||||
{
|
|
||||||
Warehouse.Put(id.ToString(), dr, this, null, tmp).Then((ok) =>
|
|
||||||
{
|
|
||||||
var (_, parsed) = Codec.Parse(content, 0, this, transmissionType);
|
|
||||||
parsed.Then(results =>
|
parsed.Then(results =>
|
||||||
{
|
{
|
||||||
var ar = results as object[];
|
var ar = results as object[];
|
||||||
@ -2066,35 +2071,47 @@ partial class DistributedConnection
|
|||||||
reply.Trigger(dr);
|
reply.Trigger(dr);
|
||||||
}).Error(ex => reply.TriggerError(ex));
|
}).Error(ex => reply.TriggerError(ex));
|
||||||
|
|
||||||
}).Error(ex => reply.TriggerError(ex));
|
};
|
||||||
|
|
||||||
|
if (template == null)
|
||||||
|
{
|
||||||
|
GetTemplate((Guid)rt[0]).Then((tmp) =>
|
||||||
|
{
|
||||||
|
// ClassId, ResourceAge, ResourceLink, Content
|
||||||
|
if (resource == null)
|
||||||
|
{
|
||||||
|
Warehouse.Put(id.ToString(), dr, this, null, tmp).Then(initResource).Error(ex => reply.TriggerError(ex));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var (_, parsed) = Codec.Parse(content, 0, this, transmissionType);
|
initResource(resource);
|
||||||
parsed.Then((results) =>
|
|
||||||
{
|
|
||||||
var ar = results as object[];
|
|
||||||
|
|
||||||
var pvs = new List<PropertyValue>();
|
|
||||||
|
|
||||||
for (var i = 0; i < ar.Length; i += 3)
|
|
||||||
pvs.Add(new PropertyValue(ar[i + 2], (ulong?)ar[i], (DateTime?)ar[i + 1]));
|
|
||||||
|
|
||||||
dr._Attach(pvs.ToArray());// (PropertyValue[])pvs);
|
|
||||||
|
|
||||||
// resourceRequests.Remove(id);
|
|
||||||
reply.Trigger(dr);
|
|
||||||
}).Error(ex => reply.TriggerError(ex));
|
|
||||||
}
|
}
|
||||||
}).Error((ex) =>
|
}).Error((ex) =>
|
||||||
{
|
{
|
||||||
reply.TriggerError(ex);
|
reply.TriggerError(ex);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (resource == null)
|
||||||
|
{
|
||||||
|
Warehouse.Put(id.ToString(), dr, this, null, template)
|
||||||
|
.Then(initResource).Error((ex) => reply.TriggerError(ex));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initResource(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}).Error((ex) =>
|
}).Error((ex) =>
|
||||||
{
|
{
|
||||||
reply.TriggerError(ex);
|
reply.TriggerError(ex);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2111,7 +2128,7 @@ partial class DistributedConnection
|
|||||||
var dataType = (TransmissionType)ar[0];
|
var dataType = (TransmissionType)ar[0];
|
||||||
var data = (byte[])ar[1];
|
var data = (byte[])ar[1];
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, dataType);
|
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
|
||||||
|
|
||||||
parsed.Then(resources => rt.Trigger(resources))
|
parsed.Then(resources => rt.Trigger(resources))
|
||||||
.Error(ex => rt.TriggerError(ex));
|
.Error(ex => rt.TriggerError(ex));
|
||||||
@ -2136,7 +2153,7 @@ partial class DistributedConnection
|
|||||||
{
|
{
|
||||||
var dataType = (TransmissionType)ar[0];
|
var dataType = (TransmissionType)ar[0];
|
||||||
var data = (byte[])ar[1];
|
var data = (byte[])ar[1];
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, dataType);
|
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
|
||||||
|
|
||||||
parsed.Then(resources => rt.Trigger(resources))
|
parsed.Then(resources => rt.Trigger(resources))
|
||||||
.Error(ex => rt.TriggerError(ex));
|
.Error(ex => rt.TriggerError(ex));
|
||||||
@ -2204,7 +2221,7 @@ partial class DistributedConnection
|
|||||||
var dataType = (TransmissionType)ar[0];
|
var dataType = (TransmissionType)ar[0];
|
||||||
var data = (byte[])ar[1];
|
var data = (byte[])ar[1];
|
||||||
//Codec.Parse(d, )
|
//Codec.Parse(d, )
|
||||||
var (_, parsed) = Codec.Parse(data, 0, this, dataType);
|
var (_, parsed) = Codec.Parse(data, 0, this, null, dataType);
|
||||||
parsed.Then(st =>
|
parsed.Then(st =>
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -2227,7 +2244,7 @@ partial class DistributedConnection
|
|||||||
var dataType = (TransmissionType)ar[0];
|
var dataType = (TransmissionType)ar[0];
|
||||||
var data = (byte[])ar[1];
|
var data = (byte[])ar[1];
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(data, 0, this, dataType);
|
var (_, parsed) = Codec.Parse(data, 0, this, null, dataType);
|
||||||
parsed.Then(st =>
|
parsed.Then(st =>
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -2268,7 +2285,7 @@ partial class DistributedConnection
|
|||||||
{
|
{
|
||||||
var content = (byte[])rt[0];
|
var content = (byte[])rt[0];
|
||||||
|
|
||||||
DataDeserializer.HistoryParser(content, 0, (uint)content.Length, resource, this)
|
DataDeserializer.HistoryParser(content, 0, (uint)content.Length, resource, this, null)
|
||||||
.Then((history) => reply.Trigger(history));
|
.Then((history) => reply.Trigger(history));
|
||||||
|
|
||||||
}).Error((ex) => reply.TriggerError(ex));
|
}).Error((ex) => reply.TriggerError(ex));
|
||||||
@ -2298,7 +2315,7 @@ partial class DistributedConnection
|
|||||||
var dataType = (TransmissionType)ar[0];
|
var dataType = (TransmissionType)ar[0];
|
||||||
var data = ar[1] as byte[];
|
var data = ar[1] as byte[];
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, dataType);
|
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
|
||||||
|
|
||||||
parsed.Then(resources => reply.Trigger(resources))
|
parsed.Then(resources => reply.Trigger(resources))
|
||||||
.Error(ex => reply.TriggerError(ex));
|
.Error(ex => reply.TriggerError(ex));
|
||||||
@ -2342,7 +2359,7 @@ partial class DistributedConnection
|
|||||||
{
|
{
|
||||||
var rid = (uint)args[0];
|
var rid = (uint)args[0];
|
||||||
|
|
||||||
Fetch(rid).Then((r) =>
|
Fetch(rid, null).Then((r) =>
|
||||||
{
|
{
|
||||||
reply.Trigger(r);
|
reply.Trigger(r);
|
||||||
});
|
});
|
||||||
|
@ -167,13 +167,45 @@ public class TypeTemplate
|
|||||||
return new Guid(hash);
|
return new Guid(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Type GetElementType(Type type) => type switch
|
static Type[] GetDistributedTypes(Type type)
|
||||||
{
|
{
|
||||||
{ IsArray: true } => type.GetElementType(),
|
if (type.IsArray)
|
||||||
// { IsEnum: true } => type.GetEnumUnderlyingType(),
|
return GetDistributedTypes(type.GetElementType());
|
||||||
(_) => type
|
else if (type.IsEnum)
|
||||||
};
|
return new Type[] { type };
|
||||||
|
else if (type.IsGenericType)
|
||||||
|
{
|
||||||
|
var genericType = type.GetGenericTypeDefinition();
|
||||||
|
var genericTypeArgs = type.GetGenericArguments();
|
||||||
|
|
||||||
|
if (genericType == typeof(List<>)
|
||||||
|
|| genericType == typeof(DistributedPropertyContext<>))
|
||||||
|
{
|
||||||
|
return GetDistributedTypes(genericTypeArgs[0]);
|
||||||
|
}
|
||||||
|
else if (genericType == typeof(Tuple<>)
|
||||||
|
|| genericType == typeof(Map<,>))
|
||||||
|
{
|
||||||
|
var rt = new List<Type>();
|
||||||
|
for (var i = 0; i < genericTypeArgs.Length; i++)
|
||||||
|
{
|
||||||
|
var depTypes = GetDistributedTypes(genericTypeArgs[i]);
|
||||||
|
foreach (var depType in depTypes)
|
||||||
|
if (!rt.Contains(depType))
|
||||||
|
rt.Add(depType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rt.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Codec.ImplementsInterface(type, typeof(IRecord))
|
||||||
|
|| Codec.ImplementsInterface(type, typeof(IResource)))
|
||||||
|
{
|
||||||
|
return new Type[] { type };
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Type[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static TypeTemplate[] GetDependencies(TypeTemplate template)
|
public static TypeTemplate[] GetDependencies(TypeTemplate template)
|
||||||
@ -205,13 +237,20 @@ public class TypeTemplate
|
|||||||
// functions
|
// functions
|
||||||
foreach (var f in tmp.functions)
|
foreach (var f in tmp.functions)
|
||||||
{
|
{
|
||||||
var frtt = Warehouse.GetTemplateByType(GetElementType(f.MethodInfo.ReturnType));
|
var functionReturnTypes = GetDistributedTypes(f.MethodInfo.ReturnType);
|
||||||
if (frtt != null)
|
//.Select(x => Warehouse.GetTemplateByType(x))
|
||||||
|
//.Where(x => x != null && !bag.Contains(x))
|
||||||
|
|
||||||
|
foreach (var functionReturnType in functionReturnTypes)
|
||||||
{
|
{
|
||||||
if (!bag.Contains(frtt))
|
var functionReturnTemplate = Warehouse.GetTemplateByType(functionReturnType);
|
||||||
|
if (functionReturnTemplate != null)
|
||||||
{
|
{
|
||||||
list.Add(frtt);
|
if (!bag.Contains(functionReturnTemplate))
|
||||||
getDependenciesFunc(frtt, bag);
|
{
|
||||||
|
list.Add(functionReturnTemplate);
|
||||||
|
getDependenciesFunc(functionReturnTemplate, bag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +258,11 @@ public class TypeTemplate
|
|||||||
|
|
||||||
for (var i = 0; i < args.Length - 1; i++)
|
for (var i = 0; i < args.Length - 1; i++)
|
||||||
{
|
{
|
||||||
var fpt = Warehouse.GetTemplateByType(GetElementType(args[i].ParameterType));
|
var fpTypes = GetDistributedTypes(args[i].ParameterType);
|
||||||
|
|
||||||
|
foreach (var fpType in fpTypes)
|
||||||
|
{
|
||||||
|
var fpt = Warehouse.GetTemplateByType(fpType);
|
||||||
if (fpt != null)
|
if (fpt != null)
|
||||||
{
|
{
|
||||||
if (!bag.Contains(fpt))
|
if (!bag.Contains(fpt))
|
||||||
@ -229,6 +272,7 @@ public class TypeTemplate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// skip DistributedConnection argument
|
// skip DistributedConnection argument
|
||||||
if (args.Length > 0)
|
if (args.Length > 0)
|
||||||
@ -236,7 +280,12 @@ public class TypeTemplate
|
|||||||
var last = args.Last();
|
var last = args.Last();
|
||||||
if (last.ParameterType != typeof(DistributedConnection))
|
if (last.ParameterType != typeof(DistributedConnection))
|
||||||
{
|
{
|
||||||
var fpt = Warehouse.GetTemplateByType(GetElementType(last.ParameterType));
|
|
||||||
|
var fpTypes = GetDistributedTypes(last.ParameterType);
|
||||||
|
|
||||||
|
foreach (var fpType in fpTypes)
|
||||||
|
{
|
||||||
|
var fpt = Warehouse.GetTemplateByType(fpType);
|
||||||
if (fpt != null)
|
if (fpt != null)
|
||||||
{
|
{
|
||||||
if (!bag.Contains(fpt))
|
if (!bag.Contains(fpt))
|
||||||
@ -247,19 +296,25 @@ public class TypeTemplate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// properties
|
// properties
|
||||||
foreach (var p in tmp.properties)
|
foreach (var p in tmp.properties)
|
||||||
{
|
{
|
||||||
var pt = Warehouse.GetTemplateByType(GetElementType(p.PropertyInfo.PropertyType));
|
var propertyTypes = GetDistributedTypes(p.PropertyInfo.PropertyType);
|
||||||
if (pt != null)
|
|
||||||
|
foreach (var propertyType in propertyTypes)
|
||||||
{
|
{
|
||||||
if (!bag.Contains(pt))
|
var propertyTemplate = Warehouse.GetTemplateByType(propertyType);
|
||||||
|
if (propertyTemplate != null)
|
||||||
{
|
{
|
||||||
bag.Add(pt);
|
if (!bag.Contains(propertyTemplate))
|
||||||
getDependenciesFunc(pt, bag);
|
{
|
||||||
|
bag.Add(propertyTemplate);
|
||||||
|
getDependenciesFunc(propertyTemplate, bag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,14 +322,19 @@ public class TypeTemplate
|
|||||||
// events
|
// events
|
||||||
foreach (var e in tmp.events)
|
foreach (var e in tmp.events)
|
||||||
{
|
{
|
||||||
var et = Warehouse.GetTemplateByType(GetElementType(e.EventInfo.EventHandlerType.GenericTypeArguments[0]));
|
var eventTypes = GetDistributedTypes(e.EventInfo.EventHandlerType.GenericTypeArguments[0]);
|
||||||
|
|
||||||
if (et != null)
|
foreach (var eventType in eventTypes)
|
||||||
{
|
{
|
||||||
if (!bag.Contains(et))
|
var eventTemplate = Warehouse.GetTemplateByType(eventType);
|
||||||
|
|
||||||
|
if (eventTemplate != null)
|
||||||
{
|
{
|
||||||
bag.Add(et);
|
if (!bag.Contains(eventTemplate))
|
||||||
getDependenciesFunc(et, bag);
|
{
|
||||||
|
bag.Add(eventTemplate);
|
||||||
|
getDependenciesFunc(eventTemplate, bag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -707,7 +767,7 @@ public class TypeTemplate
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasParent (Type type)
|
public static bool HasParent(Type type)
|
||||||
{
|
{
|
||||||
var parent = type.BaseType;
|
var parent = type.BaseType;
|
||||||
|
|
||||||
@ -887,7 +947,7 @@ public class TypeTemplate
|
|||||||
|
|
||||||
offset += dts;
|
offset += dts;
|
||||||
|
|
||||||
(dts, var value) = Codec.Parse(data, offset, null);
|
(dts, var value) = Codec.Parse(data, offset, null, null);
|
||||||
|
|
||||||
offset += dts;
|
offset += dts;
|
||||||
|
|
||||||
|
@ -51,33 +51,6 @@ namespace Test
|
|||||||
static async Task Main(string[] args)
|
static async Task Main(string[] args)
|
||||||
{
|
{
|
||||||
|
|
||||||
//foreach (var a in ma)
|
|
||||||
// Console.WriteLine(a);
|
|
||||||
|
|
||||||
//var route = "users/{id:int:min(1)}/{name:string}.jpg";
|
|
||||||
//var route = "users/{id}/{name}.jpg";
|
|
||||||
//var rr = getRouteRegex(route);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// var m = rr.Match("users/222/fun.jpg");
|
|
||||||
|
|
||||||
// Console.WriteLine(m.Value);
|
|
||||||
|
|
||||||
// var escaped = Regex.Escape(route);
|
|
||||||
|
|
||||||
// var replace = Regex.Replace(route, @"\{([^}]*)\}", @"\{([^}]*)\}");
|
|
||||||
|
|
||||||
// var ss = route.Split('{', '}');
|
|
||||||
|
|
||||||
//var regex = "users/\"
|
|
||||||
//Regex regex = new Regex(@"\(([^()]+)\)*");
|
|
||||||
|
|
||||||
//foreach (Match match in regex.Matches("You id is (1) and your number is (0000000000)"))
|
|
||||||
//{
|
|
||||||
// Console.WriteLine(match.Value);
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Create stores to keep objects.
|
// Create stores to keep objects.
|
||||||
var system = await Warehouse.Put("mem", new MemoryStore());
|
var system = await Warehouse.Put("mem", new MemoryStore());
|
||||||
var server = await Warehouse.Put("mem/server", new DistributedServer());
|
var server = await Warehouse.Put("mem/server", new DistributedServer());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user