2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-05-06 11:32:59 +00:00

AsyncReply is awaitable

This commit is contained in:
Ahmed Zamil 2019-07-21 05:29:58 +03:00
parent 48e450ffc4
commit 2d9f61c0d9
26 changed files with 561 additions and 213 deletions

View File

@ -11,7 +11,7 @@
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
<RepositoryUrl>https://github.com/esiur/esiur-dotnet/</RepositoryUrl>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Version>1.1.0</Version>
<Version>1.2.0</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -185,7 +185,7 @@ namespace Esiur.Stores.MongoDB
return rt;
}
AsyncReply Parse(BsonValue value)
IAsyncReply<object> Parse(BsonValue value)
{
if (value.BsonType == BsonType.Document)
{
@ -217,7 +217,7 @@ namespace Esiur.Stores.MongoDB
return rt;
}
else
return new AsyncReply(null);
return new AsyncReply<object>(null);
}
else if (value.BsonType == BsonType.Array)
{
@ -233,12 +233,12 @@ namespace Esiur.Stores.MongoDB
}
else if (value.BsonType == BsonType.DateTime)
{
return new AsyncReply(value.ToUniversalTime());
return new AsyncReply<object>(value.ToUniversalTime());
}
else
{
return new AsyncReply(value.RawValue);
return new AsyncReply<object>(value.RawValue);
}
}
@ -633,7 +633,7 @@ namespace Esiur.Stores.MongoDB
var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>();
AsyncBag<PropertyValue> bag = new AsyncBag<PropertyValue>();
AsyncBag<PropertyValue[]> bag = new AsyncBag<PropertyValue[]>();
foreach (var p in properties)
bag.Add(GetPropertyRecordByAge(resource, p.Name, fromAge, toAge));
@ -642,7 +642,7 @@ namespace Esiur.Stores.MongoDB
bag.Then(x =>
{
var list = new KeyList<PropertyTemplate, PropertyValue>();
var list = new KeyList<PropertyTemplate, PropertyValue[]>();
for (var i = 0; i < x.Length; i++)
list.Add(properties[i], x[i]);
@ -696,5 +696,10 @@ namespace Esiur.Stores.MongoDB
return true;
}
public AsyncReply<bool> Open(Structure settings)
{
return new AsyncReply<bool>(true);
}
}
}

View File

@ -171,7 +171,7 @@ namespace Esiur.Data
var result = (StructureComparisonResult)data[offset++];
AsyncReply previous = null;
IAsyncReply<Structure> previous = null;
// string[] previousKeys = null;
// DataType[] previousTypes = null;
@ -362,7 +362,7 @@ namespace Esiur.Data
/// <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>
/// <returns>Structure</returns>
public static AsyncReply Parse(byte[] data, uint offset, DistributedConnection connection, DataType dataType = DataType.Unspecified)
public static IAsyncReply<object> Parse(byte[] data, uint offset, DistributedConnection connection, DataType dataType = DataType.Unspecified)
{
uint size;
return Parse(data, offset, out size, connection);
@ -377,10 +377,9 @@ namespace Esiur.Data
/// <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>
/// <returns>Value</returns>
public static AsyncReply Parse(byte[] data, uint offset, out uint size, DistributedConnection connection, DataType dataType = DataType.Unspecified)
public static IAsyncReply<object> Parse(byte[] data, uint offset, out uint size, DistributedConnection connection, DataType dataType = DataType.Unspecified)
{
var reply = new AsyncReply();
bool isArray;
DataType t;
@ -480,40 +479,40 @@ namespace Esiur.Data
return new AsyncReply<object>(null);
case DataType.Bool:
return new AsyncReply<bool>(data.GetBoolean(offset));
return new AsyncReply<object>(data.GetBoolean(offset));
case DataType.UInt8:
return new AsyncReply<byte>(data[offset]);
return new AsyncReply<object>(data[offset]);
case DataType.Int8:
return new AsyncReply<sbyte>((sbyte)data[offset]);
return new AsyncReply<object>((sbyte)data[offset]);
case DataType.Char:
return new AsyncReply<char>(data.GetChar(offset));
return new AsyncReply<object>(data.GetChar(offset));
case DataType.Int16:
return new AsyncReply<short>(data.GetInt16(offset));
return new AsyncReply<object>(data.GetInt16(offset));
case DataType.UInt16:
return new AsyncReply<ushort>(data.GetUInt16(offset));
return new AsyncReply<object>(data.GetUInt16(offset));
case DataType.Int32:
return new AsyncReply<int>(data.GetInt32(offset));
return new AsyncReply<object>(data.GetInt32(offset));
case DataType.UInt32:
return new AsyncReply<uint>(data.GetUInt32(offset));
return new AsyncReply<object>(data.GetUInt32(offset));
case DataType.Int64:
return new AsyncReply<long>(data.GetInt64(offset));
return new AsyncReply<object>(data.GetInt64(offset));
case DataType.UInt64:
return new AsyncReply<ulong>(data.GetUInt64(offset));
return new AsyncReply<object>(data.GetUInt64(offset));
case DataType.Float32:
return new AsyncReply<float>(data.GetFloat32(offset));
return new AsyncReply<object>(data.GetFloat32(offset));
case DataType.Float64:
return new AsyncReply<double>(data.GetFloat64(offset));
return new AsyncReply<object>(data.GetFloat64(offset));
case DataType.String:
return new AsyncReply<string>(data.GetString(offset, contentLength));
@ -525,7 +524,7 @@ namespace Esiur.Data
return ParseDistributedResource(data, offset, connection);
case DataType.DateTime:
return new AsyncReply<DateTime>(data.GetDateTime(offset));
return new AsyncReply<object>(data.GetDateTime(offset));
case DataType.Structure:
return ParseStructure(data, offset, contentLength, connection);
@ -694,7 +693,7 @@ namespace Esiur.Data
//
var result = (ResourceComparisonResult)data[offset++];
AsyncReply previous = null;
IAsyncReply<IResource> previous = null;
if (result == ResourceComparisonResult.Null)
previous = new AsyncReply<IResource>(null);
@ -716,7 +715,7 @@ namespace Esiur.Data
{
result = (ResourceComparisonResult)data[offset++];
AsyncReply current = null;
IAsyncReply<IResource> current = null;
if (result == ResourceComparisonResult.Null)
{

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace Esiur.Engine
{
public class AsyncAwaiter<T> : INotifyCompletion
{
Action callback = null;
T result;
private bool completed;
public AsyncAwaiter(AsyncReply<T> reply)
{
reply.Then(x =>
{
completed = true;
result = x;
callback?.Invoke();
});
}
public T GetResult()
{
return result;
}
public bool IsCompleted => completed;
//From INotifyCompletion
public void OnCompleted(Action continuation)
{
Console.WriteLine("Continue....");
}
}
}

View File

@ -30,21 +30,23 @@ using System.Threading.Tasks;
namespace Esiur.Engine
{
public class AsyncBag<T>:AsyncReply
public class AsyncBag<T>: AsyncReply<T[]>
{
//Dictionary<AsyncReply, T> results = new Dictionary<AsyncReply, T>();
List<AsyncReply> replies = new List<AsyncReply>();
List<IAsyncReply<T>> replies = new List<IAsyncReply<T>>();
List<T> results = new List<T>();
int count = 0;
bool sealedBag = false;
/*
public AsyncBag<T> Then(Action<T[]> callback)
{
base.Then(new Action<object>(o => callback((T[])o)));
return this;
}
*/
public void Seal()
{
@ -72,7 +74,7 @@ namespace Esiur.Engine
}
}
public void Add(AsyncReply reply)
public void Add(IAsyncReply<T> reply)
{
if (!sealedBag)
{
@ -82,6 +84,12 @@ namespace Esiur.Engine
//results.Add(reply, default(T));
}
public void AddBag(AsyncBag<T> bag)
{
foreach (var r in bag.replies)
Add(r);
}
public AsyncBag()
{

View File

@ -63,23 +63,21 @@ namespace Esiur.Engine
{
AsyncReply.ErrorType type;
ExceptionCode code;
public readonly ErrorType Type;
public readonly ExceptionCode Code;
public AsyncReply.ErrorType Type => type;
public ExceptionCode Code => code;
public AsyncException(AsyncReply.ErrorType type, ushort code, string message)
: base(type == AsyncReply.ErrorType.Management ? ((ExceptionCode)code).ToString() : message)
public AsyncException(ErrorType type, ushort code, string message)
: base(type == ErrorType.Management ? ((ExceptionCode)code).ToString() : message)
{
this.type = type;
this.code = (ExceptionCode)code;
this.Type = type;
this.Code = (ExceptionCode)code;
}
public override string ToString()
{
return code.ToString() + ": " + Message;
return Code.ToString() + ": " + Message;
}
}
}

View File

@ -30,18 +30,18 @@ using System.Threading.Tasks;
namespace Esiur.Engine
{
public class AsyncQueue<T> : AsyncReply
public class AsyncQueue<T> : AsyncReply<T>
{
List<AsyncReply<T>> list = new List<AsyncReply<T>>();
//Action<T> callback;
object queueLock = new object();
public AsyncQueue<T> Then(Action<T> callback)
{
base.Then(new Action<object>(o => callback((T)o)));
//public AsyncQueue<T> Then(Action<T> callback)
//{
// base.Then(new Action<object>(o => callback((T)o)));
return this;
}
//return this;
//}
public void Add(AsyncReply<T> reply)
{

View File

@ -32,17 +32,9 @@ namespace Esiur.Engine
{
public class AsyncReply
{
public enum ErrorType
{
Management,
Exception
}
public enum ProgressType
{
Execution,
Network,
}
protected List<Action<object>> callbacks = new List<Action<object>>();
protected object result;

View File

@ -29,13 +29,175 @@ using System.Text;
using System.Threading.Tasks;
using Esiur.Resource;
using System.Reflection;
using System.Threading;
using System.Runtime.CompilerServices;
namespace Esiur.Engine
{
public class AsyncReply<T>: AsyncReply
public class AsyncReply<T>: IAsyncReply<T>
{
protected List<Action<T>> callbacks = new List<Action<T>>();
protected T result;
protected List<Action<AsyncException>> errorCallbacks = new List<Action<AsyncException>>();
public AsyncReply<T> Then(Action<T> callback)
protected List<Action<ProgressType, int, int>> progressCallbacks = new List<Action<ProgressType, int, int>>();
protected List<Action<T>> chunkCallbacks = new List<Action<T>>();
//List<AsyncAwaiter> awaiters = new List<AsyncAwaiter>();
object callbacksLock = new object();
protected bool resultReady = false;
AsyncException exception;
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
public bool Ready
{
get { return resultReady; }
}
public object Result
{
get { return result; }
}
public IAsyncReply<T> Then(Action<T> callback)
{
callbacks.Add(callback);
if (resultReady)
callback(result);
return this;
}
public IAsyncReply<T> Error(Action<AsyncException> callback)
{
errorCallbacks.Add(callback);
if (exception != null)
{
callback(exception);
tcs.SetException(exception);
}
return this;
}
public IAsyncReply<T> Progress(Action<ProgressType, int, int> callback)
{
progressCallbacks.Add(callback);
return this;
}
public IAsyncReply<T> Chunk(Action<T> callback)
{
chunkCallbacks.Add(callback);
return this;
}
public void Trigger(object result)
{
lock (callbacksLock)
{
if (resultReady)
return;
this.result = (T)result;
resultReady = true;
foreach (var cb in callbacks)
cb((T)result);
tcs.TrySetResult(result);
}
}
public void TriggerError(AsyncException exception)
{
if (resultReady)
return;
this.exception = exception;
lock (callbacksLock)
{
foreach (var cb in errorCallbacks)
cb(exception);
}
tcs.TrySetException(exception);
}
public void TriggerProgress(ProgressType type, int value, int max)
{
if (resultReady)
return;
lock (callbacksLock)
{
foreach (var cb in progressCallbacks)
cb(type, value, max);
}
}
public void TriggerChunk(object value)
{
if (resultReady)
return;
lock (callbacksLock)
{
foreach (var cb in chunkCallbacks)
cb((T)value);
}
}
public AsyncAwaiter<T> GetAwaiter()
{
return new AsyncAwaiter<T>(this);
}
public Task Task
{
get
{
return tcs.Task;
}
}
public AsyncReply()
{
}
public AsyncReply(T result)
{
resultReady = true;
tcs.SetResult(result);
this.result = result;
}
/*
public AsyncReply<T> Then(Action<T> callback)
{
base.Then(new Action<object>(o => callback((T)o)));
return this;
@ -46,6 +208,15 @@ namespace Esiur.Engine
Trigger((object)result);
}
public Task<bool> MoveNext(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public void Dispose()
{
}
public AsyncReply()
{
@ -67,13 +238,15 @@ namespace Esiur.Engine
}
}
public T Current => throw new NotImplementedException();
public AsyncReply(T result)
: base(result)
{
}
*/
}
}

12
Esiur/Engine/ErrorType.cs Normal file
View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Engine
{
public enum ErrorType
{
Management,
Exception
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace Esiur.Engine
{
public interface IAsyncReply<out T>//IAsyncEnumerator<T>
{
IAsyncReply<T> Then(Action<T> callback);
IAsyncReply<T> Error(Action<AsyncException> callback);
IAsyncReply<T> Progress(Action<ProgressType, int, int> callback);
IAsyncReply<T> Chunk(Action<T> callback);
void Trigger(object result);
void TriggerError(AsyncException exception);
void TriggerProgress(ProgressType type, int value, int max);
void TriggerChunk(object value);
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Engine
{
public enum ProgressType
{
Execution,
Network,
}
}

View File

@ -7,9 +7,11 @@
<PackageLicenseUrl>https://github.com/esiur/esiur-dotnet/blob/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>1.1.0</Version>
<Version>1.2.3</Version>
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
<Authors>Ahmed Kh. Zamil</Authors>
<AssemblyVersion>1.2.3.0</AssemblyVersion>
<Company>Esiur Foundation</Company>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@ -22,6 +24,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="Engine\AsyncReply.cs" />
<Compile Remove="Net\UDP\UDPServer.cs" />
</ItemGroup>
@ -30,12 +33,14 @@
</ItemGroup>
<ItemGroup>
<None Include="Engine\AsyncReply.cs" />
<None Include="Net\UDP\UDPServer.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Diagnostics.StackTrace" Version="4.3.0" />
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
<PackageReference Include="System.Interactive.Async" Version="3.2.0" />
<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
<PackageReference Include="System.Net.Security" Version="4.3.1" />

View File

@ -50,7 +50,7 @@ namespace Esiur.Net.DataLink
public void Destroy()
{
throw new NotImplementedException();
}
}
}

View File

@ -36,8 +36,36 @@ namespace Esiur.Net.HTTP
{
public class IIPoWS: HTTPFilter
{
[ResourceProperty]
public DistributedServer DistributedServer
{
get;
set;
}
public override bool Execute(HTTPConnection sender)
{
if (DistributedServer == null)
return false;
var tcpSocket = sender.Unassign();
if (tcpSocket == null)
return false;
var httpServer = sender.Parent;
var wsSocket = new WSSocket(tcpSocket);
httpServer.RemoveConnection(sender);
var iipConnection = new DistributedConnection();
DistributedServer.AddConnection(iipConnection);
iipConnection.Assign(wsSocket);
wsSocket.Begin();
return true;
/*
if (sender.Request.Filename.StartsWith("/iip/"))
{
// find the service
@ -73,6 +101,7 @@ namespace Esiur.Net.HTTP
}
return false;
*/
}
private void IipConnection_OnReady(DistributedConnection sender)

View File

@ -524,13 +524,13 @@ namespace Esiur.Net.IIP
switch (packet.Report)
{
case IIPPacketReport.ManagementError:
IIPReportError(packet.CallbackId, AsyncReply.ErrorType.Management, packet.ErrorCode, null);
IIPReportError(packet.CallbackId, ErrorType.Management, packet.ErrorCode, null);
break;
case IIPPacketReport.ExecutionError:
IIPReportError(packet.CallbackId, AsyncReply.ErrorType.Exception, packet.ErrorCode, packet.ErrorMessage);
IIPReportError(packet.CallbackId, ErrorType.Exception, packet.ErrorCode, packet.ErrorMessage);
break;
case IIPPacketReport.ProgressReport:
IIPReportProgress(packet.CallbackId, AsyncReply.ProgressType.Execution, packet.ProgressValue, packet.ProgressMax);
IIPReportProgress(packet.CallbackId, ProgressType.Execution, packet.ProgressValue, packet.ProgressMax);
break;
case IIPPacketReport.ChunkStream:
IIPReportChunk(packet.CallbackId, packet.Content);
@ -735,5 +735,11 @@ namespace Esiur.Net.IIP
// nothing to do
return true;
}
public AsyncReply<bool> Open(Structure settings)
{
return new AsyncReply<bool>(true);
}
}
}

View File

@ -50,7 +50,7 @@ namespace Esiur.Net.IIP
Dictionary<Guid, ResourceTemplate> templates = new Dictionary<Guid, ResourceTemplate>();
KeyList<uint, AsyncReply> requests = new KeyList<uint, AsyncReply>();
KeyList<uint, IAsyncReply<object>> requests = new KeyList<uint, IAsyncReply<object>>();
uint callbackCounter = 0;
@ -62,7 +62,7 @@ namespace Esiur.Net.IIP
/// <param name="action">Packet action.</param>
/// <param name="args">Arguments to send.</param>
/// <returns></returns>
internal AsyncReply<object[]> SendRequest(IIPPacket.IIPPacketAction action, params object[] args)
internal IAsyncReply<object[]> SendRequest(IIPPacket.IIPPacketAction action, params object[] args)
{
var reply = new AsyncReply<object[]>();
callbackCounter++;
@ -100,11 +100,11 @@ namespace Esiur.Net.IIP
Send(bl.ToArray());
}
internal AsyncReply SendInvokeByArrayArguments(uint instanceId, byte index, object[] parameters)
internal AsyncReply<object> SendInvokeByArrayArguments(uint instanceId, byte index, object[] parameters)
{
var pb = Codec.ComposeVarArray(parameters, this, true);
var reply = new AsyncReply();
var reply = new AsyncReply<object>();
callbackCounter++;
var bl = new BinaryList((byte)(0x40 | (byte)Packets.IIPPacket.IIPPacketAction.InvokeFunctionArrayArguments),
callbackCounter, instanceId, index, pb);
@ -114,11 +114,11 @@ namespace Esiur.Net.IIP
return reply;
}
internal AsyncReply SendInvokeByNamedArguments(uint instanceId, byte index, Structure parameters)
internal AsyncReply<object> SendInvokeByNamedArguments(uint instanceId, byte index, Structure parameters)
{
var pb = Codec.ComposeStructure(parameters, this, true, true, true);
var reply = new AsyncReply();
var reply = new AsyncReply<object>();
callbackCounter++;
var bl = new BinaryList((byte)(0x40 | (byte)Packets.IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments),
callbackCounter, instanceId, index, pb);
@ -129,12 +129,12 @@ namespace Esiur.Net.IIP
}
void SendError(AsyncReply.ErrorType type, uint callbackId, ushort errorCode, string errorMessage = "")
void SendError(ErrorType type, uint callbackId, ushort errorCode, string errorMessage = "")
{
var msg = DC.ToBytes(errorMessage);
if (type == AsyncReply.ErrorType.Management)
if (type == ErrorType.Management)
SendParams((byte)(0xC0 | (byte)IIPPacket.IIPPacketReport.ManagementError), callbackId, errorCode);
else if (type == AsyncReply.ErrorType.Exception)
else if (type == ErrorType.Exception)
SendParams((byte)(0xC0 | (byte)IIPPacket.IIPPacketReport.ExecutionError), callbackId, errorCode, (ushort)msg.Length, msg);
}
@ -165,13 +165,13 @@ namespace Esiur.Net.IIP
});
}
void IIPReportError(uint callbackId, AsyncReply.ErrorType errorType, ushort errorCode, string errorMessage)
void IIPReportError(uint callbackId, ErrorType errorType, ushort errorCode, string errorMessage)
{
var req = requests.Take(callbackId);
req?.TriggerError(new AsyncException(errorType, errorCode, errorMessage));
}
void IIPReportProgress(uint callbackId, AsyncReply.ProgressType type, int value, int max)
void IIPReportProgress(uint callbackId, ProgressType type, int value, int max)
{
var req = requests[callbackId];
req?.TriggerProgress(type, value, max);
@ -379,7 +379,7 @@ namespace Esiur.Net.IIP
{
if (res.Instance.Applicable(session, ActionType.Attach, null) == Ruling.Denied)
{
SendError(AsyncReply.ErrorType.Management, callback, 6);
SendError(ErrorType.Management, callback, 6);
return;
}
@ -415,7 +415,7 @@ namespace Esiur.Net.IIP
{
// reply failed
//SendParams(0x80, r.Instance.Id, r.Instance.Age, r.Instance.Serialize(false, this));
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
}
});
}
@ -459,7 +459,7 @@ namespace Esiur.Net.IIP
else
{
// reply failed
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
}
});
}
@ -480,7 +480,7 @@ namespace Esiur.Net.IIP
else
{
// reply failed
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
}
});
}
@ -492,20 +492,20 @@ namespace Esiur.Net.IIP
{
if (store == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.StoreNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.StoreNotFound);
return;
}
if (!(store is IStore))
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceIsNotStore);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceIsNotStore);
return;
}
// check security
if (store.Instance.Applicable(session, ActionType.CreateResource, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.CreateDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.CreateDenied);
return;
}
@ -517,7 +517,7 @@ namespace Esiur.Net.IIP
if (parent != null)
if (parent.Instance.Applicable(session, ActionType.AddChild, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.AddChildDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.AddChildDenied);
return;
}
@ -537,7 +537,7 @@ namespace Esiur.Net.IIP
if (type == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ClassNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ClassNotFound);
return;
}
@ -614,13 +614,13 @@ namespace Esiur.Net.IIP
{
if (r == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
if (r.Instance.Store.Instance.Applicable(session, ActionType.Delete, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.DeleteDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.DeleteDenied);
return;
}
@ -628,7 +628,7 @@ namespace Esiur.Net.IIP
SendReply(IIPPacket.IIPPacketAction.DeleteResource, callback);
//SendParams((byte)0x84, callback);
else
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.DeleteFailed);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.DeleteFailed);
});
}
@ -638,14 +638,14 @@ namespace Esiur.Net.IIP
{
if (r == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
// if (!r.Instance.Store.Instance.Applicable(r, session, ActionType.InquireAttributes, null))
if (r.Instance.Applicable(session, ActionType.InquireAttributes, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ViewAttributeDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ViewAttributeDenied);
return;
}
@ -660,7 +660,7 @@ namespace Esiur.Net.IIP
SendReply(all ? IIPPacket.IIPPacketAction.GetAllAttributes : IIPPacket.IIPPacketAction.GetAttributes, callback,
Codec.ComposeStructure(st, this, true, true, true));
else
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.GetAttributesFailed);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.GetAttributesFailed);
});
}
@ -671,7 +671,7 @@ namespace Esiur.Net.IIP
{
if (parent == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
@ -679,19 +679,19 @@ namespace Esiur.Net.IIP
{
if (child == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
if (parent.Instance.Applicable(this.session, ActionType.AddChild, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.AddChildDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.AddChildDenied);
return;
}
if (child.Instance.Applicable(this.session, ActionType.AddParent, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.AddParentDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.AddParentDenied);
return;
}
@ -710,7 +710,7 @@ namespace Esiur.Net.IIP
{
if (parent == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
@ -718,19 +718,19 @@ namespace Esiur.Net.IIP
{
if (child == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
if (parent.Instance.Applicable(this.session, ActionType.RemoveChild, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.AddChildDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.AddChildDenied);
return;
}
if (child.Instance.Applicable(this.session, ActionType.RemoveParent, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.AddParentDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.AddParentDenied);
return;
}
@ -749,13 +749,13 @@ namespace Esiur.Net.IIP
{
if (resource == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
if (resource.Instance.Applicable(this.session, ActionType.Rename, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.RenameDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.RenameDenied);
return;
}
@ -771,7 +771,7 @@ namespace Esiur.Net.IIP
{
if (resource == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
@ -789,7 +789,7 @@ namespace Esiur.Net.IIP
{
if (resource == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
@ -807,13 +807,13 @@ namespace Esiur.Net.IIP
{
if (r == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
if (r.Instance.Store.Instance.Applicable(session, ActionType.UpdateAttributes, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeDenied);
return;
}
@ -825,7 +825,7 @@ namespace Esiur.Net.IIP
if (r.Instance.RemoveAttributes(attrs))
SendReply(all ? IIPPacket.IIPPacketAction.ClearAllAttributes : IIPPacket.IIPPacketAction.ClearAttributes, callback);
else
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeFailed);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeFailed);
});
}
@ -836,13 +836,13 @@ namespace Esiur.Net.IIP
{
if (r == null)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
return;
}
if (r.Instance.Store.Instance.Applicable(session, ActionType.UpdateAttributes, null) != Ruling.Allowed)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeDenied);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeDenied);
return;
}
@ -852,7 +852,7 @@ namespace Esiur.Net.IIP
SendReply(clearAttributes ? IIPPacket.IIPPacketAction.ClearAllAttributes : IIPPacket.IIPPacketAction.ClearAttributes,
callback);
else
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeFailed);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeFailed);
});
});
@ -868,7 +868,7 @@ namespace Esiur.Net.IIP
else
{
// reply failed
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.TemplateNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.TemplateNotFound);
}
});
}
@ -882,7 +882,7 @@ namespace Esiur.Net.IIP
else
{
// reply failed
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.TemplateNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.TemplateNotFound);
}
});
}
@ -899,7 +899,7 @@ namespace Esiur.Net.IIP
else
{
// reply failed
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.TemplateNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.TemplateNotFound);
}
});
}
@ -916,7 +916,7 @@ namespace Esiur.Net.IIP
var list = r.Where(x => x.Instance.Applicable(session, ActionType.Attach, null) != Ruling.Denied).ToArray();
if (list.Length == 0)
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
else
SendReply(IIPPacket.IIPPacketAction.QueryLink, callback, Codec.ComposeResourceArray(list, this, true));
//}
@ -973,7 +973,7 @@ namespace Esiur.Net.IIP
{
if (r.Instance.Applicable(session, ActionType.Execute, ft) == Ruling.Denied)
{
SendError(AsyncReply.ErrorType.Management, callback,
SendError(ErrorType.Management, callback,
(ushort)ExceptionCode.InvokeDenied);
return;
}
@ -1009,7 +1009,7 @@ namespace Esiur.Net.IIP
}
catch(Exception ex)
{
SendError(AsyncReply.ErrorType.Exception, callback, 0, ex.ToString());
SendError(ErrorType.Exception, callback, 0, ex.ToString());
return;
}
@ -1038,14 +1038,15 @@ namespace Esiur.Net.IIP
//await t;
//SendParams((byte)0x90, callback, Codec.Compose(res, this));
}
else if (rt is AsyncReply) //(rt.GetType().IsGenericType && (rt.GetType().GetGenericTypeDefinition() == typeof(AsyncReply<>)))
else if (rt.GetType().GetTypeInfo().IsGenericType
&& rt.GetType().GetGenericTypeDefinition() == typeof(IAsyncReply<>))
{
(rt as AsyncReply).Then(res =>
(rt as IAsyncReply<object>).Then(res =>
{
SendReply(IIPPacket.IIPPacketAction.InvokeFunctionArrayArguments, callback, Codec.Compose(res, this));
}).Error(ex =>
{
SendError(AsyncReply.ErrorType.Exception, callback, (ushort)ex.Code, ex.Message);
SendError(ErrorType.Exception, callback, (ushort)ex.Code, ex.Message);
}).Progress((pt, pv, pm) =>
{
SendProgress(callback, pv, pm);
@ -1119,7 +1120,7 @@ namespace Esiur.Net.IIP
{
if (r.Instance.Applicable(session, ActionType.Execute, ft) == Ruling.Denied)
{
SendError(AsyncReply.ErrorType.Management, callback,
SendError(ErrorType.Management, callback,
(ushort)ExceptionCode.InvokeDenied);
return;
}
@ -1150,7 +1151,7 @@ namespace Esiur.Net.IIP
}
catch (Exception ex)
{
SendError(AsyncReply.ErrorType.Exception, callback, 0, ex.ToString());
SendError(ErrorType.Exception, callback, 0, ex.ToString());
return;
}
@ -1177,14 +1178,16 @@ namespace Esiur.Net.IIP
});
}
else if (rt is AsyncReply)
{
(rt as AsyncReply).Then(res =>
// else if (rt is AsyncReply)
else if (rt.GetType().GetTypeInfo().IsGenericType
&& rt.GetType().GetGenericTypeDefinition() == typeof(IAsyncReply<>))
{
(rt as IAsyncReply<object>).Then(res =>
{
SendReply(IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments, callback, Codec.Compose(res, this));
}).Error(ex =>
{
SendError(AsyncReply.ErrorType.Exception, callback, (ushort)ex.Code, ex.Message);
SendError(ErrorType.Exception, callback, (ushort)ex.Code, ex.Message);
}).Progress((pt, pv, pm) =>
{
SendProgress(callback, pv, pm);
@ -1376,13 +1379,13 @@ namespace Esiur.Net.IIP
if (r.Instance.Applicable(session, ActionType.SetProperty, pt, this) == Ruling.Denied)
{
SendError(AsyncReply.ErrorType.Exception, callback, (ushort)ExceptionCode.SetPropertyDenied);
SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.SetPropertyDenied);
return;
}
if (!pi.CanWrite)
{
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ReadOnlyProperty);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ReadOnlyProperty);
return;
}
@ -1405,14 +1408,14 @@ namespace Esiur.Net.IIP
}
catch(Exception ex)
{
SendError(AsyncReply.ErrorType.Exception, callback, 0, ex.Message);
SendError(ErrorType.Exception, callback, 0, ex.Message);
}
}
else
{
// pt found, pi not found, this should never happen
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.PropertyNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.PropertyNotFound);
}
}
@ -1421,13 +1424,13 @@ namespace Esiur.Net.IIP
else
{
// property not found
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.PropertyNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.PropertyNotFound);
}
}
else
{
// resource not found
SendError(AsyncReply.ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
}
});
}
@ -1718,7 +1721,7 @@ namespace Esiur.Net.IIP
SendRequest(IIPPacket.IIPPacketAction.ResourceChildren, resource.Instance.Id).Then(ar =>
{
var d = (byte[])ar;
var d = (byte[])ar[0];
Codec.ParseResourceArray(d, 0, (uint)d.Length, this).Then(resources =>
{
rt.Trigger(resources);
@ -1734,7 +1737,7 @@ namespace Esiur.Net.IIP
SendRequest(IIPPacket.IIPPacketAction.ResourceParents, resource.Instance.Id).Then(ar =>
{
var d = (byte[])ar;
var d = (byte[])ar[0];
Codec.ParseResourceArray(d, 0, (uint)d.Length, this).Then(resources =>
{
rt.Trigger(resources);

View File

@ -234,7 +234,7 @@ namespace Esiur.Net.IIP
Instance.EmitResourceEvent(null, null, et.Name, args);
}
public AsyncReply _InvokeByNamedArguments(byte index, Structure namedArgs)
public AsyncReply<object> _InvokeByNamedArguments(byte index, Structure namedArgs)
{
if (destroyed)
throw new Exception("Trying to access destroyed object");
@ -246,7 +246,7 @@ namespace Esiur.Net.IIP
return connection.SendInvokeByNamedArguments(instanceId, index, namedArgs);
}
public AsyncReply _InvokeByArrayArguments(byte index, object[] args)
public AsyncReply<object> _InvokeByArrayArguments(byte index, object[] args)
{
if (destroyed)
throw new Exception("Trying to access destroyed object");
@ -263,7 +263,7 @@ namespace Esiur.Net.IIP
{
var ft = Instance.Template.GetFunctionTemplate(binder.Name);
var reply = new AsyncReply();
var reply = new AsyncReply<object>();
if (isAttached && ft!=null)
{
@ -358,12 +358,12 @@ namespace Esiur.Net.IIP
/// <param name="index">Zero-based property index.</param>
/// <param name="value">Value</param>
/// <returns>Indicator when the property is set.</returns>
internal AsyncReply _Set(byte index, object value)
internal AsyncReply<object> _Set(byte index, object value)
{
if (index >= properties.Length)
return null;
var reply = new AsyncReply();
var reply = new AsyncReply<object>();
var parameters = Codec.Compose(value, connection);
connection.SendRequest(Packets.IIPPacket.IIPPacketAction.SetProperty, instanceId, index, parameters).Then((res) =>

View File

@ -35,6 +35,7 @@ namespace Esiur.Resource
{
public interface IStore:IResource
{
AsyncReply<bool> Open(Structure settings);
AsyncReply<IResource> Get(string path);
AsyncReply<IResource> Retrieve(uint iid);
bool Put(IResource resource);

View File

@ -30,7 +30,7 @@ namespace Esiur.Resource.Template
if (Expansion != null)
{
var exp = DC.ToBytes(Expansion);
return BinaryList.ToBytes((byte)(0x10 | (IsVoid ? 0x8 : 0x0)), exp.Length, exp, (byte)name.Length, name);
return BinaryList.ToBytes((byte)(0x10 | (IsVoid ? 0x8 : 0x0)), (byte)name.Length, name, exp.Length, exp);
}
else
return BinaryList.ToBytes((byte)(IsVoid ? 0x8 : 0x0), (byte)name.Length, name);

View File

@ -66,17 +66,17 @@ namespace Esiur.Resource.Template
{
var rexp = DC.ToBytes(ReadExpansion);
var wexp = DC.ToBytes(WriteExpansion);
return BinaryList.ToBytes((byte)(0x38 | pv), wexp.Length, wexp, rexp.Length, rexp, (byte)name.Length, name);
return BinaryList.ToBytes((byte)(0x38 | pv), (byte)name.Length, name, wexp.Length, wexp, rexp.Length, rexp);
}
else if (WriteExpansion != null)
{
var wexp = DC.ToBytes(WriteExpansion);
return BinaryList.ToBytes((byte)(0x30 | pv), wexp.Length, wexp, (byte)name.Length, name);
return BinaryList.ToBytes((byte)(0x30 | pv), (byte)name.Length, name, wexp.Length, wexp);
}
else if (ReadExpansion != null)
{
var rexp = DC.ToBytes(ReadExpansion);
return BinaryList.ToBytes((byte)(0x28 | pv), rexp.Length, rexp, (byte)name.Length, name);
return BinaryList.ToBytes((byte)(0x28 | pv), (byte)name.Length, name, rexp.Length, rexp);
}
else
return BinaryList.ToBytes((byte)(0x20 | pv), (byte)name.Length, name);

View File

@ -228,7 +228,7 @@ namespace Esiur.Resource.Template
od.classId = data.GetGuid(offset);
offset += 16;
od.className = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
od.className = data.GetString(offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
od.version = data.GetInt32(offset);
@ -250,7 +250,7 @@ namespace Esiur.Resource.Template
string expansion = null;
var hasExpansion = ((data[offset] & 0x10) == 0x10);
var isVoid = ((data[offset++] & 0x08) == 0x08);
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
var name = data.GetString(offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
if (hasExpansion) // expansion ?

View File

@ -53,6 +53,7 @@ namespace Esiur.Resource
public static event StoreConnectedEvent StoreConnected;
public static event StoreDisconnectedEvent StoreDisconnected;
static KeyList<string, IStore> protocols = new KeyList<string, IStore>();
/// <summary>
/// Get a store by its name.
@ -234,7 +235,7 @@ namespace Esiur.Resource
/// </summary>
/// <param name="path"></param>
/// <returns>Resource instance.</returns>
public static AsyncReply<IResource> Get(string path)
public static AsyncReply<IResource> Get(string path, Structure settings = null, IResource parent = null, IPermissionsManager manager = null)
{
var p = path.Split('/');
@ -265,6 +266,41 @@ namespace Esiur.Resource
return new AsyncReply<IResource>(res);
}
// Should we create a new store ?
if (path.Contains("://"))
{
var url = path.Split(new string[] { "://" }, 2, StringSplitOptions.None);
var hostname = url[1].Split(new char[] { '/' }, 2)[0];
var pathname = string.Join("/", url[1].Split(new char[] { '/' }).Skip(1));
var rt = new AsyncReply<IResource>();
if (protocols.ContainsKey(url[0]))
{
var handler = protocols[url[0]];
var store = Activator.CreateInstance(handler.GetType()) as IStore;
Put(store, url[0] + "://" + hostname, null, parent, null, 0, manager);
store.Open(settings).Then(x => {
if (pathname.Length > 0 && pathname != "")
store.Get(pathname).Then(r => {
rt.Trigger(r);
}).Error(e => rt.TriggerError(e));
else
rt.Trigger(store);
}).Error(e => {
rt.TriggerError(e);
Warehouse.Remove(store);
});
}
return rt;
}
return new AsyncReply<IResource>(null);
}

View File

@ -75,5 +75,10 @@ namespace Esiur.Stores
{
return true;
}
public AsyncReply<bool> Open(Structure settings)
{
return new AsyncReply<bool>(true);
}
}
}

View File

@ -36,10 +36,10 @@ namespace Test
return Level;
}
[ResourceFunction]
public double Divide(float nominator, float denominator, DistributedConnection sender)
[ResourceFunction("Divide takes two arguments nominator and denominator")]
public double Divide(float n, float d, DistributedConnection sender)
{
return nominator / denominator;
return n / d;
}
[ResourceFunction]
@ -50,7 +50,7 @@ namespace Test
return Level;
}
[ResourceFunction]
[ResourceFunction("use it with next()")]
public IEnumerable<string> Enum(int count)
{
var msg = new string[] { "Have you throught what if a function has multiple returns ?", "So you can return chunks of IO operation that not yet finished.", "Also, what about the progress ?", "This is an example of both.", "Use it anyway you like" };
@ -62,7 +62,7 @@ namespace Test
}
}
[ResourceFunction]
[ResourceFunction("Stream returns progress")]
public AsyncReply<string> Stream(int count)
{
var reply = new AsyncReply<string>();
@ -73,7 +73,7 @@ namespace Test
timer = new Timer((x) =>
{
reply.TriggerProgress(AsyncReply.ProgressType.Execution, count, 22);
reply.TriggerProgress(ProgressType.Execution, count, 22);
if (count % 2 == 0 && msgCounter < msg.Length)
reply.TriggerChunk(msg[msgCounter++]);

View File

@ -43,15 +43,10 @@ namespace Test
static DistributedResource remoteObject;
static void Main(string[] args)
{
MainAsync().Wait();
//Thread.Sleep(-1);
}
static async Task MainAsync()
{
static async Task Main(string[] args)
{
//AsyncContext.Run(() => ());
// Create stores to keep objects.
@ -59,65 +54,71 @@ namespace Test
var remote = Warehouse.New<MemoryStore>("remote");
var mongo = Warehouse.New<MongoDBStore>("db");
/*
var system = await Warehouse.Get("mem://system").Task;
var remote = await Warehouse.Get("mem://remote").Task;
var mongo = await Warehouse.Get("mongo://db").Task;
var iip = await Warehouse.Get("iip://:5000").Task;
var iws = await Warehouse.Get("iipows://:5001", new Structure() { ["iip"] = iip }).Task;
*/
var ok = await Warehouse.Open();
// Open the warehouse
var ok = await Warehouse.Open().Task;
// Create new object if the store is empty
if (mongo.Count == 0)
myObject = Warehouse.New<MyObject>("my", mongo, null,
new UserPermissionsManager(new Structure()
{
["demo@localhost"] = new Structure()
{
["Subtract"] = new Structure { ["Execute"] = "yes" },
["Stream"] = new Structure { ["Execute"] = "yes" },
["_attach"] = "yes",
["_get_attributes"] = "yes",
["_set_attributes"] = "yes",
}
}));
else
Warehouse.Get("db/my").Then((o) => { myObject = (MyObject)o; });
// Create new distributed server object
var iip = Warehouse.New<DistributedServer>("iip", system);
// Set membership which handles authentication.
iip.Membership = Warehouse.New<MyMembership>("ms", system);
// Start the server on port 5000.
iip.Start(new TCPSocket(new System.Net.IPEndPoint(System.Net.IPAddress.Any, 5000)), 600000, 60000);
// Create http server to handle IIP over Websockets
var http = Warehouse.New<HTTPServer>("http", system);
http.Start(new TCPSocket(new System.Net.IPEndPoint(System.Net.IPAddress.Any, 5001)), 600000, 60000);
// Create IIP over Websocket HTTP module and give it to HTTP server.
var wsOverHttp = Warehouse.New<IIPoWS>("IIPoWS", system, http);
Warehouse.StoreConnected += (store, name) =>
{
if (store.Instance.Parents.Contains(iip))
// Create new object if the store is empty
if (mongo.Count == 0)
myObject = Warehouse.New<MyObject>("my", mongo, null,
new UserPermissionsManager(new Structure()
{
store.Get("local/js").Then((r) =>
["demo@localhost"] = new Structure()
{
if (r != null)
{
dynamic d = r;
d.send("Welcome");
}
});
}
};
["Subtract"] = new Structure { ["Execute"] = "yes" },
["Stream"] = new Structure { ["Execute"] = "yes" },
["_attach"] = "yes",
["_get_attributes"] = "yes",
["_set_attributes"] = "yes",
}
}));
else
myObject =(MyObject) (await Warehouse.Get("db/my"));//.Then((o) => { myObject = (MyObject)o; });
// Start testing
// TestClient();
// Create new distributed server object
var iip = Warehouse.New<DistributedServer>("iip", system);
// Set membership which handles authentication.
iip.Membership = Warehouse.New<MyMembership>("ms", system);
// Start the server on port 5000.
iip.Start(new TCPSocket(new System.Net.IPEndPoint(System.Net.IPAddress.Any, 5000)), 600000, 60000);
// Create http server to handle IIP over Websockets
var http = Warehouse.New<HTTPServer>("http", system);
http.Start(new TCPSocket(new System.Net.IPEndPoint(System.Net.IPAddress.Any, 5001)), 600000, 60000);
// Create IIP over Websocket HTTP module and give it to HTTP server.
var wsOverHttp = Warehouse.New<IIPoWS>("IIPoWS", system, http);
wsOverHttp.DistributedServer = iip;
Warehouse.StoreConnected += (store, name) =>
{
if (store.Instance.Parents.Contains(iip))
{
store.Get("local/js").Then((r) =>
{
if (r != null)
{
dynamic d = r;
d.send("Welcome");
}
});
}
};
// Start testing
// TestClient();
var running = true;
@ -137,6 +138,8 @@ namespace Test
else
Console.WriteLine(myObject.Name + " " + myObject.Level);
}
}
private static void TestClient()
@ -148,12 +151,12 @@ namespace Test
// Put the client in our memory store
var remote = Warehouse.GetStore("remote");
Warehouse.Put(client, "Endpoint", remote);
client.OnReady += async (c) =>
{
// Get remote object from the server.
remoteObject = await client.Get("db/my").Task as DistributedResource;
//remoteObject = await client.Get("db/my").Task as DistributedResource;
dynamic x = remoteObject;
@ -169,13 +172,13 @@ namespace Test
Console.WriteLine("LevelUp " + parameters[0] + " " + parameters[1]);
});
(x.Stream(10) as AsyncReply).Then(r =>
(x.Stream(10) as AsyncReply<object>).Then(r =>
{
Console.WriteLine("Stream ended: " + r);
}).Chunk(r=>
}).Chunk(r =>
{
Console.WriteLine("Chunk..." + r);
}).Progress((t, v, m)=> Console.WriteLine("Processing {0}/{1}", v, m));
}).Progress((t, v, m) => Console.WriteLine("Processing {0}/{1}", v, m));
var rt = await x.Subtract(10).Task;