2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-09-13 12:43:17 +00:00

AsyncReply

This commit is contained in:
2025-08-19 15:24:05 +03:00
parent 39da379569
commit 46b7744852
15 changed files with 1473 additions and 1721 deletions

View File

@@ -38,18 +38,19 @@ namespace Esiur.Core;
[AsyncMethodBuilder(typeof(AsyncReplyBuilder))]
public class AsyncReply
{
//public bool Debug = false;
protected List<Action<object>> callbacks = new List<Action<object>>();
protected object result;
protected List<Action<AsyncException>> errorCallbacks = new List<Action<AsyncException>>();
protected List<Action<AsyncException>> errorCallbacks = null;
protected List<Action<ProgressType, int, int>> progressCallbacks = new List<Action<ProgressType, int, int>>();
protected List<Action<ProgressType, uint, uint>> progressCallbacks = null;
protected List<Action<object>> chunkCallbacks = new List<Action<object>>();
protected List<Action<object>> chunkCallbacks = null;
protected List<Action<object>> propagationCallbacks = null;
protected List<Action<byte, string>> warningCallbacks = null;
//List<AsyncAwaiter> awaiters = new List<AsyncAwaiter>();
object asyncLock = new object();
@@ -77,15 +78,8 @@ public class AsyncReply
if (resultReady)
return result;
//if (Debug)
// Console.WriteLine($"AsyncReply: {Id} Wait");
//mutex = new AutoResetEvent(false);
mutex.WaitOne();
//if (Debug)
// Console.WriteLine($"AsyncReply: {Id} Wait ended");
if (exception != null)
throw exception;
@@ -183,34 +177,52 @@ public class AsyncReply
public AsyncReply Error(Action<AsyncException> callback)
{
// lock (callbacksLock)
// {
if (errorCallbacks == null)
errorCallbacks = new List<Action<AsyncException>>();
errorCallbacks.Add(callback);
if (exception != null)
callback(exception);
return this;
//}
}
public AsyncReply Progress(Action<ProgressType, int, int> callback)
public AsyncReply Progress(Action<ProgressType, uint, uint> callback)
{
//lock (callbacksLock)
//{
if (progressCallbacks == null)
progressCallbacks = new List<Action<ProgressType, uint, uint>>();
progressCallbacks.Add(callback);
return this;
//}
}
public AsyncReply Warning(Action<byte, string> callback)
{
if (warningCallbacks == null)
warningCallbacks = new List<Action<byte, string>>();
warningCallbacks.Add(callback);
return this;
}
public AsyncReply Chunk(Action<object> callback)
{
// lock (callbacksLock)
// {
if (chunkCallbacks == null)
chunkCallbacks = new List<Action<object>>();
chunkCallbacks.Add(callback);
return this;
// }
}
public AsyncReply Propagation(Action<object> callback)
{
if (propagationCallbacks == null)
propagationCallbacks = new List<Action<object>>();
propagationCallbacks.Add(callback);
return this;
}
public AsyncReply Trigger(object result)
@@ -259,32 +271,57 @@ public class AsyncReply
else
this.exception = new AsyncException(exception);
// lock (callbacksLock)
// {
foreach (var cb in errorCallbacks)
cb(this.exception);
// }
if (errorCallbacks != null)
{
foreach (var cb in errorCallbacks)
cb(this.exception);
}
else
{
// no error handlers found
throw exception;
}
mutex?.Set();
return this;
}
public AsyncReply TriggerProgress(ProgressType type, int value, int max)
public AsyncReply TriggerProgress(ProgressType type, uint value, uint max)
{
//timeout?.Dispose();
//lock (callbacksLock)
//{
foreach (var cb in progressCallbacks)
cb(type, value, max);
//}
if (progressCallbacks != null)
foreach (var cb in progressCallbacks)
cb(type, value, max);
return this;
}
public AsyncReply TriggerWarning(byte level, string message)
{
//timeout?.Dispose();
if (warningCallbacks != null)
foreach (var cb in warningCallbacks)
cb(level, message);
return this;
}
public AsyncReply TriggerPropagation(object value)
{
//timeout?.Dispose();
if (propagationCallbacks != null)
foreach (var cb in propagationCallbacks)
cb(value);
return this;
}
public AsyncReply TriggerChunk(object value)
{
@@ -292,12 +329,10 @@ public class AsyncReply
//timeout?.Dispose();
//lock (callbacksLock)
//{
foreach (var cb in chunkCallbacks)
cb(value);
if (chunkCallbacks != null)
foreach (var cb in chunkCallbacks)
cb(value);
//}
return this;
}

View File

@@ -45,7 +45,7 @@ public class AsyncReply<T> : AsyncReply
return this;
}
public new AsyncReply<T> Progress(Action<ProgressType, int, int> callback)
public new AsyncReply<T> Progress(Action<ProgressType, uint, uint> callback)
{
base.Progress(callback);
return this;

View File

@@ -7,5 +7,6 @@ namespace Esiur.Core;
public enum ErrorType
{
Management,
Exception
Exception,
Warning
}

View File

@@ -40,10 +40,11 @@ public enum ExceptionCode : ushort
AddToStoreFailed,
NotAttached,
AlreadyListened,
AlreadyUnlistened,
AlreadyUnsubscribed,
NotSubscribable,
ParseError,
Timeout,
NotSupported,
NotImplemented
NotImplemented,
NotAllowed
}

View File

@@ -47,47 +47,110 @@ public static class Codec
static AsyncParser[][] FixedAsyncParsers = new AsyncParser[][]
{
new AsyncParser[]{
DataDeserializer.NullParserAsync,
DataDeserializer.BooleanFalseParserAsync,
DataDeserializer.BooleanTrueParserAsync,
DataDeserializer.NotModifiedParserAsync,
},
new AsyncParser[]{
DataDeserializer.UInt8ParserAsync,
DataDeserializer.Int8ParserAsync,
DataDeserializer.Char8ParserAsync,
DataDeserializer.LocalResourceParser8Async,
DataDeserializer.ResourceParser8Async,
},
new AsyncParser[]{
DataDeserializer.Int16ParserAsync,
DataDeserializer.UInt16ParserAsync,
DataDeserializer.Char16ParserAsync,
DataDeserializer.LocalResourceParser16Async,
DataDeserializer.ResourceParser16Async,
},
new AsyncParser[]{
DataDeserializer.Int32ParserAsync,
DataDeserializer.UInt32ParserAsync,
DataDeserializer.Float32ParserAsync,
DataDeserializer.LocalResourceParser32Async,
DataDeserializer.ResourceParser32Async,
},
new AsyncParser[]{
DataDeserializer.Int64ParserAsync,
DataDeserializer.UInt64ParserAsync,
DataDeserializer.Float64ParserAsync,
DataDeserializer.DateTimeParserAsync,
},
new AsyncParser[]
{
DataDeserializer.Int128ParserAsync, // int 128
DataDeserializer.UInt128ParserAsync, // uint 128
DataDeserializer.Float128ParserAsync,
}
};
static AsyncParser[] DynamicAsyncParsers = new AsyncParser[]
{
DataDeserializer.RawDataParserAsync,
DataDeserializer.StringParserAsync,
DataDeserializer.ListParserAsync,
DataDeserializer.ResourceListParserAsync,
DataDeserializer.RecordListParserAsync,
};
static AsyncParser[] TypedAsyncParsers = new AsyncParser[]
{
DataDeserializer.RecordParserAsync,
DataDeserializer.TypedListParserAsync,
DataDeserializer.TypedMapParserAsync,
DataDeserializer.TupleParserAsync,
DataDeserializer.EnumParserAsync,
DataDeserializer.ConstantParserAsync,
};
static SyncParser[][] FixedParsers = new SyncParser[][]
{
new SyncParser[]{
DataDeserializer.NullParser,
DataDeserializer.BooleanFalseParser,
DataDeserializer.BooleanTrueParser,
DataDeserializer.NotModifiedParser,
},
new AsyncParser[]{
DataDeserializer.ByteParser,
DataDeserializer.SByteParser,
new SyncParser[]{
DataDeserializer.UInt8Parser,
DataDeserializer.Int8Parser,
DataDeserializer.Char8Parser,
DataDeserializer.LocalResourceParser8,
DataDeserializer.ResourceParser8,
},
new AsyncParser[]{
new SyncParser[]{
DataDeserializer.Int16Parser,
DataDeserializer.UInt16Parser,
DataDeserializer.Char16Parser,
DataDeserializer.LocalResourceParser16,
DataDeserializer.ResourceParser16,
},
new AsyncParser[]{
new SyncParser[]{
DataDeserializer.Int32Parser,
DataDeserializer.UInt32Parser,
DataDeserializer.Float32Parser,
DataDeserializer.LocalResourceParser32,
DataDeserializer.ResourceParser32,
},
new AsyncParser[]{
new SyncParser[]{
DataDeserializer.Int64Parser,
DataDeserializer.UInt64Parser,
DataDeserializer.Float64Parser,
DataDeserializer.DateTimeParser,
},
new AsyncParser[]
new SyncParser[]
{
DataDeserializer.Int128Parser, // int 128
DataDeserializer.UInt128Parser, // uint 128
DataDeserializer.Float128Parser,
}
};
};
static AsyncParser[] DynamicAsyncParsers = new AsyncParser[]
static SyncParser[] DynamicParsers = new SyncParser[]
{
DataDeserializer.RawDataParser,
DataDeserializer.StringParser,
@@ -96,7 +159,7 @@ public static class Codec
DataDeserializer.RecordListParser,
};
static AsyncParser[] TypedAsyncParsers = new AsyncParser[]
static SyncParser[] TypedParsers = new SyncParser[]
{
DataDeserializer.RecordParser,
DataDeserializer.TypedListParser,
@@ -106,7 +169,6 @@ public static class Codec
DataDeserializer.ConstantParser,
};
/// <summary>
/// Parse a value
/// </summary>

View File

@@ -373,7 +373,7 @@ public static class DataDeserializer
var initRecord = (TypeTemplate template) =>
{
ListParser(data, offset, length, connection, requestSequence).Then(r =>
ListParserAsync(data, offset, length, connection, requestSequence).Then(r =>
{
var ar = (object[])r;
@@ -684,6 +684,31 @@ public static class DataDeserializer
return rt.ToArray();
}
public static (uint, ulong, object[]) LimitedCountListParser(byte[] data, uint offset, ulong length, uint countLimit = uint.MaxValue)
{
var rt = new List<object>();
while (length > 0 && rt.Count < countLimit)
{
var (cs, reply) = Codec.ParseSync(data, offset);
rt.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
return (offset, length, rt.ToArray());
}
public static AsyncReply TypedMapParserAsync(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
{
// get key type
@@ -826,6 +851,21 @@ public static class DataDeserializer
var type = typeof(ValueTuple<,,,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3]));
}
else if (ar.Length == 5)
{
var type = typeof(ValueTuple<,,,,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3], ar[4]));
}
else if (ar.Length == 6)
{
var type = typeof(ValueTuple<,,,,,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3], ar[4], ar[5]));
}
else if (ar.Length == 7)
{
var type = typeof(ValueTuple<,,,,,,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3], ar[4], ar[5], ar[6]));
}
});
return rt;
@@ -896,9 +936,12 @@ public static class DataDeserializer
var type = typeof(ValueTuple<,,,,,,>).MakeGenericType(types.ToArray());
return Activator.CreateInstance(type, results[0], results[1], results[2], results[3], results[4], results[5], results[6]);
}
throw new Exception("Unknown tuple length.");
}
public static AsyncReply TypedListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
public static AsyncReply TypedListParserAsync(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
{
var rt = new AsyncBag<object>();
@@ -932,13 +975,47 @@ public static class DataDeserializer
return rt;
}
public static object TypedListParser(byte[] data, uint offset, uint length)
{
public static AsyncBag<PropertyValue> PropertyValueArrayParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
// get the type
var (hdrCs, rep) = RepresentationType.Parse(data, offset);
offset += hdrCs;
length -= hdrCs;
var runtimeType = rep.GetRuntimeType();
var list = new List<object>();
while (length > 0)
{
var (cs, reply) = Codec.ParseSync(data, offset);
list.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
var rt = Array.CreateInstance(runtimeType, list.Count);
Array.Copy(list.ToArray(), rt, rt.Length);
return rt;
}
public static AsyncBag<PropertyValue> PropertyValueArrayParserAsync(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
{
var rt = new AsyncBag<PropertyValue>();
ListParser(data, offset, length, connection, requestSequence).Then(x =>
ListParserAsync(data, offset, length, connection, requestSequence).Then(x =>
{
var ar = (object[])x;
var pvs = new List<PropertyValue>();
@@ -954,7 +1031,8 @@ public static class DataDeserializer
}
public static (uint, AsyncReply<PropertyValue>) PropertyValueParser(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
public static (uint, AsyncReply<PropertyValue>) PropertyValueParserAsync(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
{
var reply = new AsyncReply<PropertyValue>();
@@ -967,15 +1045,22 @@ public static class DataDeserializer
var (valueSize, results) = Codec.ParseAsync(data, offset, connection, requestSequence);
results.Then(value =>
if (results is AsyncReply)
{
reply.Trigger(new PropertyValue(value, age, date));
});
(results as AsyncReply).Then(value =>
{
reply.Trigger(new PropertyValue(value, age, date));
});
}
else
{
reply.Trigger(new PropertyValue(results, age, date));
}
return (16 + valueSize, reply);
}
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> HistoryParser(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection, uint[] requestSequence)
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> HistoryParserAsync(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection, uint[] requestSequence)
{
//var count = (int)toAge - (int)fromAge;
@@ -994,7 +1079,7 @@ public static class DataDeserializer
var cs = data.GetUInt32(offset, Endian.Little);
offset += 4;
var (len, pv) = PropertyValueParser(data, offset, connection, requestSequence);
var (len, pv) = PropertyValueParserAsync(data, offset, connection, requestSequence);
bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection));
offset += len;

View File

@@ -102,7 +102,7 @@ public static class DataSerializer
var rt = new byte[16];
fixed (byte* ptr = rt)
*((decimal*)ptr) = v;
return (TransmissionTypeIdentifier.Float128, rt);
return (TransmissionTypeIdentifier.Decimal128, rt);
}
@@ -131,7 +131,7 @@ public static class DataSerializer
rt.AddRange(template.ClassId.Data);
rt.Add(ct.Index);
return (TransmissionTypeIdentifier.Enum, rt.ToArray());
return (TransmissionTypeIdentifier.TypedEnum, rt.ToArray());
}
public static (TransmissionTypeIdentifier, byte[]) UInt8Composer(object value, DistributedConnection connection)
@@ -146,7 +146,7 @@ public static class DataSerializer
public static unsafe (TransmissionTypeIdentifier, byte[]) Char8Composer(object value, DistributedConnection connection)
{
return (TransmissionTypeIdentifier.Char8, new byte[] { (byte)(char)value });
return (TransmissionTypeIdentifier.Char8, new byte[] { (byte)(char)value });
}
public static unsafe (TransmissionTypeIdentifier, byte[]) Char16Composer(object value, DistributedConnection connection)
@@ -241,7 +241,7 @@ public static class DataSerializer
// .ToArray();
//}
public static (TransmissionTypeIdentifier, byte[]) PropertyValueArrayComposer(object value, DistributedConnection connection)
public static (TransmissionTypeIdentifier, byte[]) PropertyValueArrayComposer(object value, DistributedConnection connection)
{
if (value == null)
return (TransmissionTypeIdentifier.Null, new byte[0]);
@@ -274,7 +274,7 @@ public static class DataSerializer
var map = (IMap)value;
foreach(var el in map.Serialize())
foreach (var el in map.Serialize())
rt.AddRange(Codec.Compose(el, connection));
return (TransmissionTypeIdentifier.TypedMap, rt.ToArray());
@@ -315,20 +315,33 @@ public static class DataSerializer
public static unsafe (TransmissionTypeIdentifier, byte[]) ResourceComposer(object value, DistributedConnection connection)
{
var resource = (IResource)value;
var rt = new byte[4];
if (resource.Instance == null || resource.Instance.IsDestroyed)
if (resource.Instance == null || resource.Instance.IsDestroyed)
{
return (TransmissionTypeIdentifier.Null, new byte[0]);
}
if (Codec.IsLocalResource(resource, connection))
{
var rid = (resource as DistributedResource).DistributedResourceInstanceId;
fixed (byte* ptr = rt)
*((uint*)ptr) = (resource as DistributedResource).DistributedResourceInstanceId;
if (rid <= 0xFF)
return (TransmissionTypeIdentifier.LocalResource8, new byte[] { (byte)rid });
else if (rid <= 0xFFFF)
{
var rt = new byte[2];
fixed (byte* ptr = rt)
*((ushort*)ptr) = (ushort)rid;
return (TransmissionTypeIdentifier.ResourceLocal, rt);
return (TransmissionTypeIdentifier.LocalResource16, rt);
}
else
{
var rt = new byte[4];
fixed (byte* ptr = rt)
*((uint*)ptr) = rid;
return (TransmissionTypeIdentifier.LocalResource32, rt);
}
}
else
{
@@ -336,11 +349,25 @@ public static class DataSerializer
//rt.Append((value as IResource).Instance.Template.ClassId, (value as IResource).Instance.Id);
connection.cache.Add(value as IResource, DateTime.UtcNow);
var rid = resource.Instance.Id;
fixed (byte* ptr = rt)
*((uint*)ptr) = resource.Instance.Id;
if (rid <= 0xFF)
return (TransmissionTypeIdentifier.RemoteResource8, new byte[] { (byte)rid });
else if (rid <= 0xFFFF)
{
var rt = new byte[2];
fixed (byte* ptr = rt)
*((ushort*)ptr) = (ushort)rid;
return (TransmissionTypeIdentifier.Resource, rt);
return (TransmissionTypeIdentifier.RemoteResource16, rt);
}
else
{
var rt = new byte[4];
fixed (byte* ptr = rt)
*((uint*)ptr) = rid;
return (TransmissionTypeIdentifier.RemoteResource32, rt);
}
}
}
@@ -400,7 +427,7 @@ public static class DataSerializer
var rt = new List<byte>();
var fields = value.GetType().GetFields();
var list = fields.Select(x => x.GetValue(value)).ToArray();
var list = fields.Select(x => x.GetValue(value)).ToArray();
var types = fields.Select(x => RepresentationType.FromType(x.FieldType).Compose()).ToArray();
rt.Add((byte)list.Length);
@@ -415,7 +442,7 @@ public static class DataSerializer
else
{
rt.AddRange(composed);
return (TransmissionTypeIdentifier.Tuple, rt.ToArray());
return (TransmissionTypeIdentifier.TypedTuple, rt.ToArray());
}
}
}

View File

@@ -33,6 +33,7 @@ using Esiur.Resource;
using Esiur.Resource.Template;
using Esiur.Security.Authority;
using Esiur.Security.Membership;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
@@ -49,6 +50,39 @@ namespace Esiur.Net.IIP;
public partial class DistributedConnection : NetworkConnection, IStore
{
public delegate void ProtocolGeneralHandler(DistributedConnection connection, TransmissionType dataType, byte[] data);
public delegate void ProtocolRequestReplyHandler(DistributedConnection connection, uint callbackId, TransmissionType dataType, byte[] data);
//ProtocolGeneralHandler[] NotificationHandlers = new ProtocolGeneralHandler[]
//{
// IIPNotificationResourceDestroyed,
// IIPNotificationResourceReassigned,
// IIPNotificationResourceMoved,
// IIPNotificationSystemFailure,
// IIPNotificationPropertyModified
//};
//ProtocolRequestReplyHandler[] RequestHandlers = new ProtocolRequestReplyHandler[]
//{
// IIPRequestAttachResource,
// IIPRequest
//};
//ProtocolRequestReplyHandler[] ReplyHandlers = new ProtocolRequestReplyHandler[]
//{
//};
//ProtocolGeneralHandler[] ExtensionHandler = new ProtocolGeneralHandler[]
//{
//};
// Delegates
public delegate void ReadyEvent(DistributedConnection sender);
public delegate void ErrorEvent(DistributedConnection sender, byte errorCode, string errorMessage);
@@ -164,6 +198,9 @@ public partial class DistributedConnection : NetworkConnection, IStore
return true;
}
/// <summary>
/// Send data to the other end as parameters
/// </summary>
@@ -373,16 +410,11 @@ public partial class DistributedConnection : NetworkConnection, IStore
lastKeepAliveSent = now;
SendRequest(IIPPacketRequest.KeepAlive)
.AddDateTime(now)
.AddUInt32(interval)
.Done()
SendRequest(IIPPacketRequest.KeepAlive, now, interval)
.Then(x =>
{
Jitter = (uint)x[1];
Jitter = (uint)x;
keepAliveTimer.Start();
//Console.WriteLine($"Keep Alive Received {Jitter}");
}).Error(ex =>
{
keepAliveTimer.Stop();
@@ -393,9 +425,6 @@ public partial class DistributedConnection : NetworkConnection, IStore
Close();
});
//Console.WriteLine("Keep Alive sent");
}
public uint KeepAliveInterval { get; set; } = 30;
@@ -417,7 +446,6 @@ public partial class DistributedConnection : NetworkConnection, IStore
if (rt <= 0)
{
var size = ends - offset;
data.HoldFor(msg, offset, size, size + (uint)(-rt));
return ends;
@@ -427,311 +455,153 @@ public partial class DistributedConnection : NetworkConnection, IStore
offset += (uint)rt;
if (packet.DataType != null)
{
var dt = packet.DataType.Value;
if (packet.DataType == null)
return offset;
var (_, parsed) = Codec.Parse(msg, dt.Offset, this, null, dt);
parsed.Then(value =>
{
if (packet.Method == IIPPacketMethod.Notification)
{
switch (packet.Notification)
{
case IIPPacketNotification.ResourceDestroyed:
IIPNotificationResourceDestroyed(value);
break;
case IIPPacketNotification.ResourceReassigned:
IIPNotificationResourceReassigned(value);
break;
case IIPPacketNotification.ResourceMoved:
IIPNotificationResourceMoved(value);
break;
case IIPPacketNotification.SystemFailure:
IIPNotificationSystemFailure(value);
break;
case IIPPacketNotification.PropertyModified:
IIPNotificationPropertyModified()
}
}
});
}
if (packet.Method == IIPPacketMethod.Notification)
{
var dt = packet.DataType.Value;
switch (packet.Notification)
{
// Invoke
case IIPPacketNotification.PropertyModified:
IIPNotificationPropertyModified(dt, msg);
break;
case IIPPacketNotification.EventOccurred:
IIPNotificationEventOccurred(dt, msg);
break;
// Manage
case IIPPacketNotification.ResourceDestroyed:
case IIPPacketEvent.ResourceReassigned:
IIPEventResourceReassigned(packet.ResourceId, packet.NewResourceId);
IIPNotificationResourceDestroyed(dt, msg);
break;
case IIPPacketEvent.ResourceDestroyed:
IIPEventResourceDestroyed(packet.ResourceId);
case IIPPacketNotification.ResourceReassigned:
IIPNotificationResourceReassigned(dt, msg);
break;
case IIPPacketEvent.PropertyUpdated:
IIPEventPropertyUpdated(packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
case IIPPacketNotification.ResourceMoved:
IIPNotificationResourceMoved(dt, msg);
break;
case IIPPacketEvent.EventOccurred:
IIPEventEventOccurred(packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
break;
case IIPPacketEvent.ChildAdded:
IIPEventChildAdded(packet.ResourceId, packet.ChildId);
break;
case IIPPacketEvent.ChildRemoved:
IIPEventChildRemoved(packet.ResourceId, packet.ChildId);
break;
case IIPPacketEvent.Renamed:
IIPEventRenamed(packet.ResourceId, packet.ResourceLink);
break;
case IIPPacketEvent.AttributesUpdated:
// @TODO: fix this
//IIPEventAttributesUpdated(packet.ResourceId, packet.Content);
case IIPPacketNotification.SystemFailure:
IIPNotificationSystemFailure(dt, msg);
break;
}
}
else if (packet.Command == IIPPacketCommand.Request)
else if (packet.Method == IIPPacketMethod.Request)
{
switch (packet.Action)
var dt = packet.DataType.Value;
switch (packet.Request)
{
// Manage
case IIPPacketRequest.AttachResource:
IIPRequestAttachResource(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketRequest.ReattachResource:
IIPRequestReattachResource(packet.CallbackId, packet.ResourceId, packet.ResourceAge);
break;
case IIPPacketRequest.DetachResource:
IIPRequestDetachResource(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketRequest.CreateResource:
//@TODO : fix this
//IIPRequestCreateResource(packet.CallbackId, packet.StoreId, packet.ResourceId, packet.Content);
break;
case IIPPacketRequest.DeleteResource:
IIPRequestDeleteResource(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketRequest.AddChild:
IIPRequestAddChild(packet.CallbackId, packet.ResourceId, packet.ChildId);
break;
case IIPPacketRequest.RemoveChild:
IIPRequestRemoveChild(packet.CallbackId, packet.ResourceId, packet.ChildId);
break;
case IIPPacketRequest.RenameResource:
IIPRequestRenameResource(packet.CallbackId, packet.ResourceId, packet.ResourceName);
break;
// Inquire
case IIPPacketRequest.TemplateFromClassName:
IIPRequestTemplateFromClassName(packet.CallbackId, packet.ClassName);
break;
case IIPPacketRequest.TemplateFromClassId:
IIPRequestTemplateFromClassId(packet.CallbackId, packet.ClassId);
break;
case IIPPacketRequest.TemplateFromResourceId:
IIPRequestTemplateFromResourceId(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketRequest.QueryLink:
IIPRequestQueryResources(packet.CallbackId, packet.ResourceLink);
break;
case IIPPacketRequest.ResourceChildren:
IIPRequestResourceChildren(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketRequest.ResourceParents:
IIPRequestResourceParents(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketRequest.ResourceHistory:
IIPRequestInquireResourceHistory(packet.CallbackId, packet.ResourceId, packet.FromDate, packet.ToDate);
break;
case IIPPacketRequest.LinkTemplates:
IIPRequestLinkTemplates(packet.CallbackId, packet.ResourceLink);
break;
// Invoke
case IIPPacketRequest.InvokeFunction:
IIPRequestInvokeFunction(packet.CallbackId, packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
IIPRequestInvokeFunction(packet.CallbackId, dt, msg);
break;
//case IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments:
// IIPRequestInvokeFunctionNamedArguments(packet.CallbackId, packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
// break;
//case IIPPacket.IIPPacketAction.GetProperty:
// IIPRequestGetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
// break;
//case IIPPacket.IIPPacketAction.GetPropertyIfModified:
// IIPRequestGetPropertyIfModifiedSince(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.ResourceAge);
// break;
case IIPPacketRequest.Listen:
IIPRequestListen(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
break;
case IIPPacketRequest.Unlisten:
IIPRequestUnlisten(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
break;
case IIPPacketRequest.SetProperty:
IIPRequestSetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
IIPRequestSetProperty(packet.CallbackId, dt, msg);
break;
// Attribute
case IIPPacketRequest.GetAllAttributes:
// @TODO : fix this
//IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
case IIPPacketRequest.Subscribe:
IIPRequestSubscribe(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.UpdateAllAttributes:
// @TODO : fix this
//IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
case IIPPacketRequest.Unsubscribe:
IIPRequestUnsubscribe(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.ClearAllAttributes:
// @TODO : fix this
//IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
// Inquire
case IIPPacketRequest.TemplateFromClassName:
IIPRequestTemplateFromClassName(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.GetAttributes:
// @TODO : fix this
//IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
case IIPPacketRequest.TemplateFromClassId:
IIPRequestTemplateFromClassId(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.UpdateAttributes:
// @TODO : fix this
//IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
case IIPPacketRequest.TemplateFromResourceId:
IIPRequestTemplateFromResourceId(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.ClearAttributes:
// @TODO : fix this
//IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
case IIPPacketRequest.Query:
IIPRequestQueryResources(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.KeepAlive:
IIPRequestKeepAlive(packet.CallbackId, packet.CurrentTime, packet.Interval);
case IIPPacketRequest.LinkTemplates:
IIPRequestLinkTemplates(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.ProcedureCall:
IIPRequestProcedureCall(packet.CallbackId, packet.Procedure, (TransmissionType)packet.DataType, msg);
case IIPPacketRequest.Token:
IIPRequestToken(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.StaticCall:
IIPRequestStaticCall(packet.CallbackId, packet.ClassId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
case IIPPacketRequest.GetResourceIdByLink:
IIPRequestGetResourceIdByLink(packet.CallbackId, dt, msg);
break;
}
}
else if (packet.Command == IIPPacketCommand.Reply)
{
switch (packet.Action)
{
// Manage
case IIPPacketRequest.AttachResource:
IIPReply(packet.CallbackId, packet.ClassId, packet.ResourceAge, packet.ResourceLink, packet.DataType, msg);
IIPRequestAttachResource(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.ReattachResource:
IIPReply(packet.CallbackId, packet.ResourceAge, packet.DataType, msg);
IIPRequestReattachResource(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.DetachResource:
IIPReply(packet.CallbackId);
IIPRequestDetachResource(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.CreateResource:
IIPReply(packet.CallbackId, packet.ResourceId);
IIPRequestCreateResource(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.DeleteResource:
case IIPPacketRequest.AddChild:
case IIPPacketRequest.RemoveChild:
case IIPPacketRequest.RenameResource:
IIPReply(packet.CallbackId);
IIPRequestDeleteResource(packet.CallbackId, dt, msg);
break;
// Inquire
case IIPPacketRequest.TemplateFromClassName:
case IIPPacketRequest.TemplateFromClassId:
case IIPPacketRequest.TemplateFromResourceId:
var content = msg.Clip(packet.DataType.Value.Offset, (uint)packet.DataType.Value.ContentLength);
IIPReply(packet.CallbackId, TypeTemplate.Parse(content));
case IIPPacketRequest.MoveResource:
IIPRequestMoveResource(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.QueryLink:
case IIPPacketRequest.ResourceChildren:
case IIPPacketRequest.ResourceParents:
case IIPPacketRequest.ResourceHistory:
case IIPPacketRequest.LinkTemplates:
IIPReply(packet.CallbackId, (TransmissionType)packet.DataType, msg);// packet.Content);
break;
// Invoke
case IIPPacketRequest.InvokeFunction:
case IIPPacketRequest.StaticCall:
case IIPPacketRequest.ProcedureCall:
IIPReplyInvoke(packet.CallbackId, (TransmissionType)packet.DataType, msg);// packet.Content);
break;
//case IIPPacket.IIPPacketAction.GetProperty:
// IIPReply(packet.CallbackId, packet.Content);
// break;
//case IIPPacket.IIPPacketAction.GetPropertyIfModified:
// IIPReply(packet.CallbackId, packet.Content);
// break;
case IIPPacketRequest.Listen:
case IIPPacketRequest.Unlisten:
case IIPPacketRequest.SetProperty:
IIPReply(packet.CallbackId);
break;
// Attribute
case IIPPacketRequest.GetAllAttributes:
case IIPPacketRequest.GetAttributes:
IIPReply(packet.CallbackId, (TransmissionType)packet.DataType, msg);// packet.Content);
break;
case IIPPacketRequest.UpdateAllAttributes:
case IIPPacketRequest.UpdateAttributes:
case IIPPacketRequest.ClearAllAttributes:
case IIPPacketRequest.ClearAttributes:
IIPReply(packet.CallbackId);
break;
// Static
case IIPPacketRequest.KeepAlive:
IIPReply(packet.CallbackId, packet.CurrentTime, packet.Jitter);
IIPRequestKeepAlive(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.ProcedureCall:
IIPRequestProcedureCall(packet.CallbackId, dt, msg);
break;
case IIPPacketRequest.StaticCall:
IIPRequestStaticCall(packet.CallbackId, dt, msg);
break;
}
}
else if (packet.Command == IIPPacketCommand.Report)
else if (packet.Method == IIPPacketMethod.Reply)
{
switch (packet.Report)
{
case IIPPacketReport.ManagementError:
IIPReportError(packet.CallbackId, ErrorType.Management, packet.ErrorCode, null);
break;
case IIPPacketReport.ExecutionError:
IIPReportError(packet.CallbackId, ErrorType.Exception, packet.ErrorCode, packet.ErrorMessage);
break;
case IIPPacketReport.ProgressReport:
IIPReportProgress(packet.CallbackId, ProgressType.Execution, packet.ProgressValue, packet.ProgressMax);
break;
case IIPPacketReport.ChunkStream:
IIPReportChunk(packet.CallbackId, (TransmissionType)packet.DataType, msg);
var dt = packet.DataType.Value;
switch (packet.Reply)
{
case IIPPacketReply.Completed:
IIPReplyCompleted(packet.CallbackId, dt, msg);
break;
case IIPPacketReply.Propagated:
IIPReplyPropagated(packet.CallbackId, dt, msg);
break;
case IIPPacketReply.PermissionError:
IIPReplyError(packet.CallbackId, dt, msg, ErrorType.Management);
break;
case IIPPacketReply.ExecutionError:
IIPReplyError(packet.CallbackId, dt, msg, ErrorType.Exception);
break;
case IIPPacketReply.Progress:
IIPReplyProgress(packet.CallbackId, dt, msg);
break;
case IIPPacketReply.Chunk:
IIPReplyChunk(packet.CallbackId, dt, msg);
break;
case IIPPacketReply.Warning:
IIPReplyWarning(packet.Extension, dt, msg);
break;
}
}
else if (packet.Method == IIPPacketMethod.Extension)
{
IIPExtensionAction(packet.Extension, packet.DataType, msg);
}
}
}
else
{
// check if the reqeust through websockets
// check if the request through Websockets
if (initialPacket)
{
@@ -755,7 +625,6 @@ public partial class DistributedConnection : NetworkConnection, IStore
HTTPConnection.Upgrade(req, res);
res.Compose(HTTPComposeOption.AllCalculateLength);
Send(res.Data);
// replace my socket with websockets
@@ -784,11 +653,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
}
}
var rt = authPacket.Parse(msg, offset, ends);
if (rt <= 0)
{
data.HoldFor(msg, ends + (uint)(-rt));
@@ -810,9 +676,6 @@ public partial class DistributedConnection : NetworkConnection, IStore
}
return offset;
//if (offset < ends)
// processPacket(msg, offset, ends, data, chunkId);
}
private void ProcessClientAuth(byte[] data)
@@ -831,9 +694,9 @@ public partial class DistributedConnection : NetworkConnection, IStore
var dataType = authPacket.DataType.Value;
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
var (_, parsed) = Codec.ParseSync(data, dataType.Offset, dataType);
var rt = (Map<byte, object>)parsed.Wait();
var rt = (Map<byte, object>)parsed;
session.RemoteHeaders = rt.Select(x => new KeyValuePair<IIPAuthPacketHeader, object>((IIPAuthPacketHeader)x.Key, x.Value));
@@ -957,8 +820,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
else if (authPacket.Event == IIPAuthPacketEvent.IAuthPlain)
{
var dataType = authPacket.DataType.Value;
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
var rt = (Map<byte, object>)parsed.Wait();
var (_, parsed) = Codec.ParseSync(data, dataType.Offset, dataType);
var rt = (Map<byte, object>)parsed;
var headers = rt.Select(x => new KeyValuePair<IIPAuthPacketIAuthHeader, object>((IIPAuthPacketIAuthHeader)x.Key, x.Value));
var iAuthRequest = new AuthorizationRequest(headers);
@@ -983,7 +846,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
.Done();
})
.Timeout(iAuthRequest.Timeout * 1000,
() => {
() =>
{
SendParams()
.AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate)
.AddUInt8((byte)ExceptionCode.Timeout)
@@ -996,8 +860,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
else if (authPacket.Event == IIPAuthPacketEvent.IAuthHashed)
{
var dataType = authPacket.DataType.Value;
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
var rt = (Map<byte, object>)parsed.Wait();
var (_, parsed) = Codec.ParseSync(data, dataType.Offset, dataType);
var rt = (Map<byte, object>)parsed;
var headers = rt.Select(x => new KeyValuePair<IIPAuthPacketIAuthHeader, object>((IIPAuthPacketIAuthHeader)x.Key, x.Value));
@@ -1033,14 +897,15 @@ public partial class DistributedConnection : NetworkConnection, IStore
.Done();
})
.Timeout(iAuthRequest.Timeout * 1000,
() => {
SendParams()
.AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate)
.AddUInt8((byte)ExceptionCode.Timeout)
.AddUInt16(7)
.AddString("Timeout")
.Done();
});
() =>
{
SendParams()
.AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate)
.AddUInt8((byte)ExceptionCode.Timeout)
.AddUInt16(7)
.AddString("Timeout")
.Done();
});
}
}
else if (authPacket.Event == IIPAuthPacketEvent.IAuthEncrypted)
@@ -1058,10 +923,9 @@ public partial class DistributedConnection : NetworkConnection, IStore
var dataType = authPacket.DataType.Value;
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
var rt = (Map<byte, object>)parsed.Wait();
var (_, parsed) = Codec.ParseSync(data, dataType.Offset, dataType);
var rt = (Map<byte, object>)parsed;
session.RemoteHeaders = rt.Select(x => new KeyValuePair<IIPAuthPacketHeader, object>((IIPAuthPacketHeader)x.Key, x.Value));
@@ -1317,9 +1181,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
var reference = authPacket.Reference;
var dataType = authPacket.DataType.Value;
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
var value = parsed.Wait();
var (_, value) = Codec.ParseSync(data, dataType.Offset, dataType);
Server.Membership.AuthorizePlain(session, reference, value)
.Then(x => ProcessAuthorization(x));
@@ -1687,33 +1549,22 @@ public partial class DistributedConnection : NetworkConnection, IStore
try
{
var ar = await SendRequest(IIPPacketRequest.QueryLink)
.AddUInt16((ushort)link.Length)
.AddUInt8Array(link)
.Done();
var id = (uint)await SendRequest(IIPPacketRequest.GetResourceIdByLink, link);
var dataType = (TransmissionType)ar[0];
var data = ar[1] as byte[];
if (dataType.Identifier == TransmissionTypeIdentifier.ResourceList)
{
// remove from suspended.
suspendedResources.Remove(r.DistributedResourceInstanceId);
// remove from suspended.
suspendedResources.Remove(r.DistributedResourceInstanceId);
// id changed ?
if (id != r.DistributedResourceInstanceId)
r.DistributedResourceInstanceId = id;
// parse them as int
var id = data.GetUInt32(8, Endian.Little);
neededResources[id] = r;
// id changed ?
if (id != r.DistributedResourceInstanceId)
r.DistributedResourceInstanceId = id;
await Fetch(id, null);
neededResources[id] = r;
Global.Log("DistributedConnection", LogType.Debug, "Restored " + id);
await Fetch(id, null);
Global.Log("DistributedConnection", LogType.Debug, "Restored " + id);
}
}
catch (AsyncException ex)
{

File diff suppressed because it is too large Load Diff

View File

@@ -68,7 +68,7 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
string link;
//ulong age;
//ulong[] ages;
protected object[] properties;
internal List<DistributedResource> parents = new List<DistributedResource>();
internal List<DistributedResource> children = new List<DistributedResource>();
@@ -174,16 +174,31 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
/// <returns></returns>
internal PropertyValue[] _Serialize()
{
var props = new PropertyValue[properties.Length];
for (byte i = 0; i < properties.Length; i++)
props[i] = new PropertyValue(properties[i], Instance.GetAge(i), Instance.GetModificationDate(i));
props[i] = new PropertyValue(properties[i],
Instance.GetAge(i),
Instance.GetModificationDate(i));
return props;
}
internal Map<byte, PropertyValue> _SerializeAfter(ulong age = 0)
{
var rt = new Map<byte, PropertyValue>();
for (byte i = 0; i < properties.Length; i++)
if (Instance.GetAge(i) > age)
rt.Add(i, new PropertyValue(properties[i],
Instance.GetAge(i),
Instance.GetModificationDate(i)));
return rt;
}
internal bool _Attach(PropertyValue[] properties)
{
if (attached)

View File

@@ -6,13 +6,14 @@ namespace Esiur.Net.Packets
{
public enum IIPPacketNotification : byte
{
// Event Manage
ResourceDestroyed = 0,
ResourceReassigned,
ResourceMoved,
SystemFailure,
// Event Invoke
PropertyModified = 0x8,
EventOccurred,
// Notification Invoke
PropertyModified = 0x0,
EventOccurred = 0x1,
// Notification Manage
ResourceDestroyed = 0x8,
ResourceReassigned = 0x9,
ResourceMoved = 0xA,
SystemFailure = 0xB,
}
}

View File

@@ -11,8 +11,8 @@ namespace Esiur.Net.Packets
Propagated = 0x1,
// Error
Permission = 0x81,
Execution = 0x82,
PermissionError = 0x81,
ExecutionError = 0x82,
// Partial
Progress = 0x10,

View File

@@ -6,29 +6,30 @@ namespace Esiur.Net.Packets
{
public enum IIPPacketRequest : byte
{
// Request Manage
AttachResource = 0x0,
ReattachResource = 0x1,
DetachResource = 0x2,
CreateResource = 0x3,
DeleteResource = 0x4,
MoveResource = 0x5,
// Request Invoke
InvokeFunction = 0x0,
SetProperty = 0x1,
Subscribe = 0x2,
Unsubscribe = 0x3,
// Request Inquire
TemplateFromClassName = 0x8,
TemplateFromClassId = 0x9,
TemplateFromResourceId = 0xA,
QueryLink = 0xB,
Query = 0xB,
LinkTemplates = 0xC,
Token = 0xD,
GetResourceIdByLink = 0xE,
// Request Invoke
InvokeFunction = 0x10,
Subscribe = 0x11,
Unsubscribe = 0x12,
SetProperty = 0x13,
// Request Manage
AttachResource = 0x10,
ReattachResource = 0x11,
DetachResource = 0x12,
CreateResource = 0x13,
DeleteResource = 0x14,
MoveResource = 0x15,
// Static calling
// Request Static
KeepAlive = 0x18,
ProcedureCall = 0x19,
StaticCall = 0x1A

View File

@@ -48,6 +48,7 @@ public class Instance
List<ulong?> ages = new();
List<DateTime?> modificationDates = new();
private ulong instanceAge;
private byte hops;
private DateTime instanceModificationDate;
uint id;
@@ -389,6 +390,16 @@ public class Instance
internal set { instanceAge = value; }
}
/// <summary>
/// Number of nodes to reach the original resource.
/// </summary>
public ulong Hops
{
get { return hops; }
internal set { hops = value; }
}
/// <summary>
/// Last modification date.
/// </summary>
@@ -443,7 +454,7 @@ public class Instance
/// <returns></returns>
public PropertyValue[] Serialize()
{
List<PropertyValue> props = new List<PropertyValue>();
var props = new List<PropertyValue>();
foreach (var pt in template.Properties)
{
@@ -459,6 +470,33 @@ public class Instance
return props.ToArray();
}
/// <summary>
/// Export all properties with ResourceProperty attributed as bytes array after a specific age.
/// </summary>
/// <returns></returns>
public Map<byte, PropertyValue> SerializeAfter(ulong age = 0)
{
var props = new Map<byte, PropertyValue>();
foreach (var pt in template.Properties)
{
IResource res;
if (resource.TryGetTarget(out res))
{
if (res.Instance.GetAge(pt.Index) > age)
{
var rt = pt.PropertyInfo.GetValue(res, null);
props.Add(pt.Index,
new PropertyValue(rt,
ages[pt.Index],
modificationDates[pt.Index]));
}
}
}
return props;
}
/*
public bool Deserialize(byte[] data, uint offset, uint length)
{

View File

@@ -652,75 +652,51 @@ public static class Warehouse
type = ResourceProxy.GetProxy(type);
/*
if (arguments != null)
{
var constructors = type.GetConstructors(System.Reflection.BindingFlags.Public);
foreach(var constructor in constructors)
{
var pi = constructor.GetParameters();
if (pi.Length == constructor.le)
}
// cast arguments
ParameterInfo[] pi = fi.GetParameters();
object[] args = new object[pi.Length];
for (var i = 0; i < pi.Length; i++)
{
if (pi[i].ParameterType == typeof(DistributedConnection))
{
args[i] = this;
}
else if (namedArgs.ContainsKey(pi[i].Name))
{
args[i] = DC.CastConvert(namedArgs[pi[i].Name], pi[i].ParameterType);
}
}
constructors[0].
}
*/
var res = Activator.CreateInstance(type) as IResource;
if (properties != null)
{
var ps = Map<string, object>.FromObject(properties);
foreach (var p in ps)
if (properties is Map<byte, object> map)
{
var template = GetTemplateByType(type);
foreach(var kvp in map)
template.GetPropertyTemplateByIndex(kvp.Key).PropertyInfo.SetValue(res, kvp.Value);
}
else
{
var ps = Map<string, object>.FromObject(properties);
var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (pi != null)
foreach (var p in ps)
{
if (pi.CanWrite)
var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (pi != null)
{
try
if (pi.CanWrite)
{
pi.SetValue(res, p.Value);
}
catch (Exception ex)
{
Global.Log(ex);
try
{
pi.SetValue(res, p.Value);
}
catch (Exception ex)
{
Global.Log(ex);
}
}
}
}
else
{
var fi = type.GetField(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (fi != null)
else
{
try
var fi = type.GetField(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (fi != null)
{
fi.SetValue(res, p.Value);
}
catch (Exception ex)
{
Global.Log(ex);
try
{
fi.SetValue(res, p.Value);
}
catch (Exception ex)
{
Global.Log(ex);
}
}
}
}
@@ -729,9 +705,6 @@ public static class Warehouse
if (store != null || parent != null || res is IStore)
{
//if (!await Put(name, res, store, parent, null, 0, manager, attributes))
// return null;
await Put(name, res, store, parent, null, 0, manager, attributes);
}