http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cluster/IClusterNode.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cluster/IClusterNode.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cluster/IClusterNode.cs new file mode 100644 index 0000000..dfdccef --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cluster/IClusterNode.cs @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Cluster +{ + using System; + using System.Collections.Generic; + + /// <summary> + /// Interface representing a single cluster node. Use <see cref="IClusterNode.Attribute{T}(string)"/> or + /// <see cref="IClusterNode.Metrics()"/> to get static and dynamic information about remote nodes. + /// You can get a list of all nodes in grid by calling <see cref="IClusterGroup.Nodes()"/> + /// on <see cref="IIgnite"/> instance. + /// <para /> + /// You can use Ignite node attributes to provide static information about a node. + /// This information is initialized once within grid, during node startup, and + /// remains the same throughout the lifetime of a node. + /// <para/> + /// All members are thread-safe and may be used concurrently from multiple threads. + /// </summary> + public interface IClusterNode { + /// <summary> + /// Globally unique node ID. A new ID is generated every time a node restarts. + /// </summary> + Guid Id + { + get; + } + + /// <summary> + /// Gets node's attribute. Attributes are assigned to nodes at startup. + /// <para /> + /// Note that attributes cannot be changed at runtime. + /// </summary> + /// <param name="name">Attribute name.</param> + /// <returns>Attribute value.</returns> + T Attribute<T>(string name); + + /// <summary> + /// Try getting node's attribute. Attributes are assigned to nodes at startup. + /// <para /> + /// Note that attributes cannot be changed at runtime. + /// </summary> + /// <param name="name">Attribute name.</param> + /// <param name="attr">Attribute value.</param> + /// <returns><code>true</code> in case such attribute exists.</returns> + bool TryGetAttribute<T>(string name, out T attr); + + /// <summary> + /// Gets all node attributes. Attributes are assigned to nodes at startup. + /// <para /> + /// Note that attributes cannot be changed at runtime. + /// </summary> + /// <returns>All node attributes.</returns> + IDictionary<string, object> Attributes(); + + /// <summary> + /// Collection of addresses this node is known by. + /// </summary> + /// <returns>Collection of addresses.</returns> + ICollection<string> Addresses + { + get; + } + + /// <summary> + /// Collection of host names this node is known by. + /// </summary> + /// <returns>Collection of host names.</returns> + ICollection<string> HostNames + { + get; + } + + /// <summary> + /// Node order within grid topology. Discovery SPIs that support node ordering will + /// assign a proper order to each node and will guarantee that discovery event notifications + /// for new nodes will come in proper order. All other SPIs not supporting ordering + /// may choose to return node startup time here. + /// </summary> + long Order + { + get; + } + + /// <summary> + /// Tests whether or not this node is a local node. + /// </summary> + bool IsLocal + { + get; + } + + /// <summary> + /// Tests whether or not this node is a daemon. + /// <p/> + /// Daemon nodes are the usual Ignite nodes that participate in topology but not + /// visible on the main APIs, i.e. they are not part of any projections. + /// <p/> + /// Daemon nodes are used primarily for management and monitoring functionality that + /// is build on Ignite and needs to participate in the topology but should be + /// excluded from "normal" topology so that it won't participate in task execution + /// or in-memory database. + /// <p/> + /// Application code should never use daemon nodes. + /// </summary> + bool IsDaemon + { + get; + } + + /// <summary> + /// Gets metrics snapshot for this node. Note that node metrics are constantly updated + /// and provide up to date information about nodes. For example, you can get + /// an idea about CPU load on remote node via <see cref="IClusterMetrics.CurrentCpuLoad"/>. + /// <para/> + /// Node metrics are updated with some delay which is directly related to heartbeat + /// frequency. For example, when used with default <code>GridTcpDiscoverySpi</code> the + /// update will happen every <code>2</code> seconds. + /// </summary> + /// <returns>Runtime metrics snapshot for this node.</returns> + IClusterMetrics Metrics(); + } +}
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cluster/IClusterNodeFilter.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cluster/IClusterNodeFilter.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cluster/IClusterNodeFilter.cs new file mode 100644 index 0000000..77eefbb --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Cluster/IClusterNodeFilter.cs @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Cluster +{ + /// <summary> + /// Represents cluster node filter. + /// </summary> + public interface IClusterNodeFilter + { + /// <summary> + /// Returns a value indicating whether provided node satisfies this predicate. + /// </summary> + /// <param name="node">Cluster node.</param> + /// <returns>Value indicating whether provided node satisfies this predicate.</returns> + bool Invoke(IClusterNode node); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IAsyncSupport.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IAsyncSupport.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IAsyncSupport.cs index f6b6551..ee98c5a 100644 --- a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IAsyncSupport.cs +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IAsyncSupport.cs @@ -18,7 +18,7 @@ namespace Apache.Ignite.Core.Common { /// <summary> - /// Allows to enable asynchronous mode on Grid APIs. + /// Allows to enable asynchronous mode on Ignite APIs. /// </summary> /// <typeparam name="TWithAsync">Type of WithAsync method result.</typeparam> public interface IAsyncSupport<out TWithAsync> where TWithAsync : IAsyncSupport<TWithAsync> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IgniteException.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IgniteException.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IgniteException.cs index 4626407..98e5389 100644 --- a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IgniteException.cs +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IgniteException.cs @@ -21,7 +21,7 @@ namespace Apache.Ignite.Core.Common using System.Runtime.Serialization; /// <summary> - /// General grid exception. Indicates any error condition within Grid. + /// General Ignite exception. Indicates any error condition within Ignite. /// </summary> [Serializable] public class IgniteException : Exception http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IgniteGuid.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IgniteGuid.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IgniteGuid.cs new file mode 100644 index 0000000..53c7151 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Common/IgniteGuid.cs @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Common +{ + using System; + using Apache.Ignite.Core.Portable; + + /// <summary> + /// Ignite guid with additional local ID. + /// </summary> + public struct IgniteGuid : IEquatable<IgniteGuid> + { + /** Global id. */ + private readonly Guid _globalId; + + /** Local id. */ + private readonly long _localId; + + /// <summary> + /// Initializes a new instance of the <see cref="IgniteGuid"/> struct. + /// </summary> + /// <param name="globalId">The global id.</param> + /// <param name="localId">The local id.</param> + public IgniteGuid(Guid globalId, long localId) + { + _globalId = globalId; + _localId = localId; + } + + /// <summary> + /// Gets the global id. + /// </summary> + public Guid GlobalId + { + get { return _globalId; } + } + + /// <summary> + /// Gets the local id. + /// </summary> + public long LocalId + { + get { return _localId; } + } + + /** <inheritDoc /> */ + public bool Equals(IgniteGuid other) + { + return _globalId.Equals(other._globalId) && _localId == other._localId; + } + + /** <inheritDoc /> */ + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj is IgniteGuid && Equals((IgniteGuid) obj); + } + + /** <inheritDoc /> */ + public override int GetHashCode() + { + unchecked + { + return (_globalId.GetHashCode() * 397) ^ _localId.GetHashCode(); + } + } + + /** <inheritDoc /> */ + public override string ToString() + { + return string.Format("IgniteGuid [GlobalId={0}, LocalId={1}]", GlobalId, LocalId); + } + + /// <summary> + /// Writes this object to the given writer. + /// </summary> + /// <param name="w">Writer.</param> + public void WritePortable(IPortableRawWriter w) + { + w.WriteGuid(GlobalId); + w.WriteLong(LocalId); + } + + /// <summary> + /// Reads this object from the given reader. + /// </summary> + /// <param name="r">Reader.</param> + public static IgniteGuid ReadPortable(IPortableRawReader r) + { + var guid = r.ReadGuid(); + + return guid == null + ? new IgniteGuid(Guid.Empty, 0) + : new IgniteGuid(guid.Value, r.ReadLong()); + } + + /// <summary> + /// Implements the operator ==. + /// </summary> + /// <param name="a">First item.</param> + /// <param name="b">Second item.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static bool operator ==(IgniteGuid a, IgniteGuid b) + { + return a.Equals(b); + } + + /// <summary> + /// Implements the operator !=. + /// </summary> + /// <param name="a">First item.</param> + /// <param name="b">Second item.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static bool operator !=(IgniteGuid a, IgniteGuid b) + { + return !(a == b); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeExecutionRejectedException.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeExecutionRejectedException.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeExecutionRejectedException.cs new file mode 100644 index 0000000..108d396 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeExecutionRejectedException.cs @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + using System.Runtime.Serialization; + using Apache.Ignite.Core.Common; + + /// <summary> + /// Indicates a situation when execution service provided by the user in configuration rejects execution. + /// </summary> + [Serializable] + public class ComputeExecutionRejectedException : IgniteException + { + /// <summary> + /// Initializes a new instance of the <see cref="ComputeExecutionRejectedException"/> class. + /// </summary> + public ComputeExecutionRejectedException() + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeExecutionRejectedException" /> class. + /// </summary> + /// <param name="message">The message that describes the error.</param> + public ComputeExecutionRejectedException(string message) + : base(message) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeExecutionRejectedException"/> class. + /// </summary> + /// <param name="info">Serialization information.</param> + /// <param name="ctx">Streaming context.</param> + protected ComputeExecutionRejectedException(SerializationInfo info, StreamingContext ctx) + : base(info, ctx) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeExecutionRejectedException"/> class. + /// </summary> + /// <param name="message">The message.</param> + /// <param name="cause">The cause.</param> + public ComputeExecutionRejectedException(string message, Exception cause) : base(message, cause) + { + // No-op. + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobAdapter.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobAdapter.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobAdapter.cs new file mode 100644 index 0000000..92c6492 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobAdapter.cs @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + + /// <summary> + /// Convenience adapter for <see cref="IComputeJob{T}"/> implementations. It provides the following functionality: + /// <ul> + /// <li> + /// Default implementation of <see cref="IComputeJob{T}.Cancel()"/> method and ability + /// to check whether cancellation occurred with <see cref="ComputeJobAdapter{T}.IsCancelled()"/> method. + /// </li> + /// <li> + /// Ability to set and get job arguments via <see cref="ComputeJobAdapter{T}.SetArguments(object[])"/> + /// and <see cref="ComputeJobAdapter{T}.Argument{T}(int)"/> methods. + /// </li> + /// </ul> + /// </summary> + [Serializable] + public abstract class ComputeJobAdapter<T> : IComputeJob<T> + { + /** Cancelled flag */ + [NonSerialized] + private volatile bool _cancelled; + + /** Arguments. */ + protected object[] Args; + + /// <summary> + /// No-arg constructor. + /// </summary> + protected ComputeJobAdapter() + { + // No-op. + } + + /// <summary> + /// Creates job with specified arguments. + /// </summary> + /// <param name="args">Optional job arguments.</param> + protected ComputeJobAdapter(params object[] args) + { + Args = args; + } + + /// <summary> + /// This method is called when system detects that completion of this + /// job can no longer alter the overall outcome (for example, when parent task + /// has already reduced the results). + /// <para /> + /// Note that job cancellation is only a hint, and it is really up to the actual job + /// instance to gracefully finish execution and exit. + /// </summary> + public void Cancel() + { + _cancelled = true; + } + + /// <summary> + /// Sets given arguments. + /// </summary> + /// <param name="args">Optional job arguments to set.</param> + public void SetArguments(params object[] args) + { + Args = args; + } + + /// <summary> + /// Sets given arguments. + /// </summary> + /// <param name="idx">Index of the argument.</param> + public TArg Argument<TArg>(int idx) + { + if (idx < 0 || idx >= Args.Length) + throw new ArgumentException("Invalid argument index: " + idx); + + return (TArg)Args[idx]; + } + + /// <summary> + /// This method tests whether or not this job was cancelled. This method + /// is thread-safe and can be called without extra synchronization. + /// <p/> + /// This method can be periodically called in <see cref="IComputeJob{T}.Execute()"/> method + /// implementation to check whether or not this job cancelled. Note that system + /// calls <see cref="IComputeJob{T}.Cancel()"/> method only as a hint and this is a responsibility of + /// the implementation of the job to properly cancel its execution. + /// </summary> + /// <returns><c>True</c> if this job was cancelled, <c>false</c> otherwise.</returns> + protected bool IsCancelled() + { + return _cancelled; + } + + /// <summary> + /// Executes this job. + /// </summary> + /// <returns> + /// Job execution result (possibly <c>null</c>). This result will be returned + /// in <see cref="IComputeJobResult{T}" /> object passed into + /// <see cref="IComputeTask{A,T,R}.Result" /> + /// on caller node. + /// </returns> + public abstract T Execute(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobFailoverException.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobFailoverException.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobFailoverException.cs new file mode 100644 index 0000000..970bd43 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobFailoverException.cs @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + using System.Runtime.Serialization; + using Apache.Ignite.Core.Common; + + /// <summary> + /// This runtime exception can be thrown from <see cref="IComputeJob{T}.Execute()"/> + /// method to force job failover to another node within task topology. + /// <see cref="IComputeFunc{T,R}"/> or <see cref="IComputeFunc{T}"/> + /// passed into any of the <see cref="ICompute"/> methods can also throw this exception + /// to force failover. + /// </summary> + [Serializable] + public class ComputeJobFailoverException : IgniteException + { + /// <summary> + /// Initializes a new instance of the <see cref="ComputeJobFailoverException"/> class. + /// </summary> + public ComputeJobFailoverException() + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeJobFailoverException" /> class. + /// </summary> + /// <param name="message">The message that describes the error.</param> + public ComputeJobFailoverException(string message) : base(message) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeJobFailoverException"/> class. + /// </summary> + /// <param name="info">Serialization information.</param> + /// <param name="ctx">Streaming context.</param> + protected ComputeJobFailoverException(SerializationInfo info, StreamingContext ctx) + : base(info, ctx) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeJobFailoverException"/> class. + /// </summary> + /// <param name="message">The message.</param> + /// <param name="cause">The cause.</param> + public ComputeJobFailoverException(string message, Exception cause) : base(message, cause) + { + // No-op. + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobResultPolicy.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobResultPolicy.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobResultPolicy.cs new file mode 100644 index 0000000..6fa0808 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeJobResultPolicy.cs @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System.Collections.Generic; + + /// <summary> + /// This enumeration provides different types of actions following the last received job result. See + /// <see cref="IComputeTask{A,T,R}.Result(IComputeJobResult{T}, IList{IComputeJobResult{T}})"/> + /// for more details. + /// </summary> + public enum ComputeJobResultPolicy + { + /// <summary> + /// Wait for results if any are still expected. If all results have been received - + /// it will start reducing results. + /// </summary> + Wait = 0, + + /// <summary> + /// Ignore all not yet received results and start reducing results. + /// </summary> + Reduce = 1, + + /// <summary> + /// Fail-over job to execute on another node. + /// </summary> + Failover = 2 + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskAdapter.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskAdapter.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskAdapter.cs new file mode 100644 index 0000000..67f7432 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskAdapter.cs @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + using System.Collections.Generic; + using Apache.Ignite.Core.Cluster; + using Apache.Ignite.Core.Common; + + /// <summary> + /// Convenience adapter for <see cref="IComputeTask{A,T,R}"/> interface + /// </summary> + public abstract class ComputeTaskAdapter<TA, T, TR> : IComputeTask<TA, T, TR> + { + /// <summary> + /// Default implementation which will wait for all jobs to complete before + /// calling <see cref="IComputeTask{A,T,R}.Reduce"/> method. + /// <p/> + /// If remote job resulted in exception <see cref="IComputeJobResult{T}.Exception()"/> + /// is not <c>null</c>), + /// then <see cref="ComputeJobResultPolicy.Failover"/> policy will be returned if + /// the exception is instance of <see cref="ClusterTopologyException"/> + /// or <see cref="ComputeExecutionRejectedException"/>, which means that + /// remote node either failed or job execution was rejected before it got a chance to start. In all + /// other cases the exception will be rethrown which will ultimately cause task to fail. + /// </summary> + /// <param name="res">Received remote Ignite executable result.</param> + /// <param name="rcvd">All previously received results.</param> + /// <returns>Result policy that dictates how to process further upcoming job results.</returns> + public virtual ComputeJobResultPolicy Result(IComputeJobResult<T> res, IList<IComputeJobResult<T>> rcvd) + { + Exception err = res.Exception(); + + if (err != null) + { + if (err is ComputeExecutionRejectedException || err is ClusterTopologyException || + err is ComputeJobFailoverException) + return ComputeJobResultPolicy.Failover; + + throw new IgniteException("Remote job threw user exception (override or implement IComputeTask.result(..) " + + "method if you would like to have automatic failover for this exception).", err); + } + + return ComputeJobResultPolicy.Wait; + } + + /// <summary> + /// This method is called to map or split Ignite task into multiple Ignite jobs. This is the + /// first method that gets called when task execution starts. + /// </summary> + /// <param name="subgrid">Nodes available for this task execution. Note that order of nodes is + /// guaranteed to be randomized by container. This ensures that every time you simply iterate + /// through Ignite nodes, the order of nodes will be random which over time should result into + /// all nodes being used equally.</param> + /// <param name="arg">Task execution argument. Can be <c>null</c>. This is the same argument + /// as the one passed into <c>ICompute.Execute()</c> methods.</param> + /// <returns> + /// Map of Ignite jobs assigned to subgrid node. If <c>null</c> or empty map is returned, + /// exception will be thrown. + /// </returns> + public abstract IDictionary<IComputeJob<T>, IClusterNode> Map(IList<IClusterNode> subgrid, TA arg); + + /// <summary> + /// Reduces (or aggregates) results received so far into one compound result to be returned to + /// caller via future. + /// <para /> + /// Note, that if some jobs did not succeed and could not be failed over then the list of + /// results passed into this method will include the failed results. Otherwise, failed + /// results will not be in the list. + /// </summary> + /// <param name="results">Received job results. Note that if task class has + /// <see cref="ComputeTaskNoResultCacheAttribute" /> attribute, then this list will be empty.</param> + /// <returns> + /// Task result constructed from results of remote executions. + /// </returns> + public abstract TR Reduce(IList<IComputeJobResult<T>> results); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskCancelledException.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskCancelledException.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskCancelledException.cs new file mode 100644 index 0000000..460e9b0 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskCancelledException.cs @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + using System.Runtime.Serialization; + using Apache.Ignite.Core.Common; + + /// <summary> + /// This exception indicates that Ignite task was cancelled. + /// </summary> + [Serializable] + public class ComputeTaskCancelledException : IgniteException + { + /// <summary> + /// Initializes a new instance of the <see cref="ComputeTaskCancelledException"/> class. + /// </summary> + public ComputeTaskCancelledException() + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeTaskCancelledException"/> class. + /// </summary> + /// <param name="message">The message that describes the error.</param> + public ComputeTaskCancelledException(string message) + : base(message) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeTaskCancelledException"/> class. + /// </summary> + /// <param name="info">Serialization information.</param> + /// <param name="ctx">Streaming context.</param> + protected ComputeTaskCancelledException(SerializationInfo info, StreamingContext ctx) + : base(info, ctx) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeTaskCancelledException"/> class. + /// </summary> + /// <param name="message">The message.</param> + /// <param name="cause">The cause.</param> + public ComputeTaskCancelledException(string message, Exception cause) : base(message, cause) + { + // No-op. + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskNoResultCacheAttribute.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskNoResultCacheAttribute.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskNoResultCacheAttribute.cs new file mode 100644 index 0000000..a58aa87 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskNoResultCacheAttribute.cs @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + + /// <summary> + /// This attribute disables caching of task results when attached to <see cref="IComputeTask{A,T,R}"/> + /// instance. Use it when number of jobs within task grows too big, or jobs themselves are too large + /// to keep in memory throughout task execution. By default all results are cached and passed into + /// <see cref="IComputeTask{A,T,R}.Result"/> + /// and <see cref="IComputeTask{A,T,R}.Reduce"/> methods. When this + /// attribute is attached to a task class, then this list of job results will always be empty. + /// </summary> + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] + public sealed class ComputeTaskNoResultCacheAttribute : Attribute + { + // No-op. + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskSplitAdapter.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskSplitAdapter.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskSplitAdapter.cs new file mode 100644 index 0000000..bf4685a --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskSplitAdapter.cs @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using Apache.Ignite.Core.Cluster; + using Apache.Ignite.Core.Common; + using Apache.Ignite.Core.Impl.Compute; + + /// <summary> + /// This class defines simplified adapter for <see cref="IComputeTask{A,T,R}"/>. This adapter can be used + /// when jobs can be randomly assigned to available Ignite nodes. This adapter is sufficient + /// in most homogeneous environments where all nodes are equally suitable for executing grid + /// job, see <see cref="Split"/> method for more details. + /// </summary> + public abstract class ComputeTaskSplitAdapter<TA, T, TR> : ComputeTaskAdapter<TA, T, TR> + { + /** Random generator */ + [ThreadStatic] + // ReSharper disable once StaticMemberInGenericType + private static Random _rnd; + + /// <summary> + /// This is a simplified version of <see cref="IComputeTask{A,T,R}.Map"/> method. + /// <p/> + /// This method basically takes given argument and splits it into a collection + /// of <see cref="IComputeJob"/> using provided grid size as indication of how many node are + /// available. These jobs will be randomly mapped to available Ignite nodes. Note that + /// if number of jobs is greater than number of Ignite nodes (i.e, grid size), the grid + /// nodes will be reused and some jobs will end up on the same Ignite nodes. + /// </summary> + /// <param name="gridSize">Number of available Ignite nodes. Note that returned number of jobs can be less, + /// equal or greater than this grid size.</param> + /// <param name="arg">Task execution argument. Can be <c>null</c>.</param> + protected abstract ICollection<IComputeJob<T>> Split(int gridSize, TA arg); + + /// <summary> + /// This method is called to map or split Ignite task into multiple Ignite jobs. This is the + /// first method that gets called when task execution starts. + /// </summary> + /// <param name="subgrid">Nodes available for this task execution. Note that order of nodes is + /// guaranteed to be randomized by container. This ensures that every time you simply iterate + /// through Ignite nodes, the order of nodes will be random which over time should result into + /// all nodes being used equally.</param> + /// <param name="arg">Task execution argument. Can be <c>null</c>. This is the same argument + /// as the one passed into <c>ICompute.Execute()</c> methods.</param> + /// <returns> + /// Map of Ignite jobs assigned to subgrid node. If <c>null</c> or empty map is returned, + /// exception will be thrown. + /// </returns> + /// <exception cref="IgniteException">Split returned no jobs.</exception> + override public IDictionary<IComputeJob<T>, IClusterNode> Map(IList<IClusterNode> subgrid, TA arg) + { + Debug.Assert(subgrid != null && subgrid.Count > 0); + + var jobs = Split(subgrid.Count, arg); + + if (jobs == null || jobs.Count == 0) + throw new IgniteException("Split returned no jobs."); + + var map = new Dictionary<IComputeJob<T>, IClusterNode>(jobs.Count); + + if (_rnd == null) + _rnd = new Random(); + + foreach (var job in jobs) + { + int idx = _rnd.Next(subgrid.Count); + + IClusterNode node = subgrid[idx]; + + map[job] = node; + } + + return map; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskTimeoutException.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskTimeoutException.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskTimeoutException.cs new file mode 100644 index 0000000..71fc568 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeTaskTimeoutException.cs @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + using System.Runtime.Serialization; + using Apache.Ignite.Core.Common; + + /// <summary> + /// Indicates that task execution timed out. + /// </summary> + [Serializable] + public class ComputeTaskTimeoutException : IgniteException + { + /// <summary> + /// Initializes a new instance of the <see cref="ComputeTaskTimeoutException"/> class. + /// </summary> + public ComputeTaskTimeoutException() + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeTaskTimeoutException"/> class. + /// </summary> + /// <param name="message">The message that describes the error.</param> + public ComputeTaskTimeoutException(string message) : base(message) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeTaskTimeoutException"/> class. + /// </summary> + /// <param name="info">Serialization information.</param> + /// <param name="ctx">Streaming context.</param> + protected ComputeTaskTimeoutException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeTaskTimeoutException"/> class. + /// </summary> + /// <param name="message">The message.</param> + /// <param name="cause">The cause.</param> + public ComputeTaskTimeoutException(string message, Exception cause) : base(message, cause) + { + // No-op. + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeUserUndeclaredException.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeUserUndeclaredException.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeUserUndeclaredException.cs new file mode 100644 index 0000000..e3c090e --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ComputeUserUndeclaredException.cs @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + using System.Runtime.Serialization; + using Apache.Ignite.Core.Common; + + /// <summary> + /// This exception is thrown when user's code throws undeclared runtime exception. By user core it is + /// assumed the code in Ignite task, Ignite job or SPI. In most cases it should be an indication of unrecoverable + /// error condition such as assertion, out of memory error, etc. + /// </summary> + [Serializable] + public class ComputeUserUndeclaredException : IgniteException + { + /// <summary> + /// Initializes a new instance of the <see cref="ComputeUserUndeclaredException"/> class. + /// </summary> + public ComputeUserUndeclaredException() + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeUserUndeclaredException"/> class. + /// </summary> + /// <param name="message">The message that describes the error.</param> + public ComputeUserUndeclaredException(string message) : base(message) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeUserUndeclaredException"/> class. + /// </summary> + /// <param name="info">Serialization information.</param> + /// <param name="ctx">Streaming context.</param> + protected ComputeUserUndeclaredException(SerializationInfo info, StreamingContext ctx) + : base(info, ctx) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="ComputeUserUndeclaredException"/> class. + /// </summary> + /// <param name="message">The message.</param> + /// <param name="cause">The cause.</param> + public ComputeUserUndeclaredException(string message, Exception cause) : base(message, cause) + { + // No-op. + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ICompute.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ICompute.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ICompute.cs new file mode 100644 index 0000000..bbb496f --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/ICompute.cs @@ -0,0 +1,274 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + using System.Collections.Generic; + using Apache.Ignite.Core.Cluster; + using Apache.Ignite.Core.Common; + + /// <summary> + /// Defines Ignite functionality for executing tasks and closures over nodes + /// in the <see cref="IClusterGroup"/>. Instance of <see cref="ICompute"/> + /// is obtained from grid projection using <see cref="IClusterGroup.Compute()"/> method. + /// <para /> + /// Note that if attempt is made to execute a computation over an empty projection (i.e. projection that does + /// not have any alive nodes), <c>ClusterGroupEmptyException</c> will be thrown out of result future. + /// <para /> + /// Ignite must select a node for a computation to be executed. The node will be selected based on the + /// underlying <c>GridLoadBalancingSpi</c>, which by default sequentially picks next available node from + /// grid projection. Other load balancing policies, such as <c>random</c> or <c>adaptive</c>, can be + /// configured as well by selecting different load balancing SPI in Ignite configuration. If your logic requires + /// some custom load balancing behavior, consider implementing <c>ComputeTask</c> in Java directly. + /// <para /> + /// Ignite guarantees that as long as there is at least one Ignite node standing, every job will be + /// executed. Jobs will automatically failover to another node if a remote node crashed or has rejected + /// execution due to lack of resources. By default, in case of failover, next load balanced node will be + /// picked for job execution. Also jobs will never be re-routed to the nodes they have failed on. This + /// behavior can be changed by configuring any of the existing or a custom <c>FailoverSpi</c> in Ignite + /// configuration. + /// <para/> + /// All members are thread-safe and may be used concurrently from multiple threads. + /// </summary> + public interface ICompute : IAsyncSupport<ICompute> + { + /// <summary> + /// Grid projection to which this compute instance belongs. + /// </summary> + IClusterGroup ClusterGroup + { + get; + } + + /// <summary> + /// Sets no-failover flag for the next executed task on this projection in the current thread. + /// If flag is set, job will be never failed over even if remote node crashes or rejects execution. + /// When task starts execution, the no-failover flag is reset, so all other task will use default + /// failover policy, unless this flag is set again. + /// </summary> + /// <returns>This compute instance for chaining calls.</returns> + ICompute WithNoFailover(); + + /// <summary> + /// Sets task timeout for the next executed task on this projection in the current thread. + /// When task starts execution, the timeout is reset, so one timeout is used only once. + /// </summary> + /// <param name="timeout">Computation timeout in milliseconds.</param> + /// <returns>This compute instance for chaining calls.</returns> + ICompute WithTimeout(long timeout); + + /// <summary> + /// Sets keep-portable flag for the next executed Java task on this projection in the current + /// thread so that task argument passed to Java and returned task results will not be + /// deserialized. + /// </summary> + /// <returns>This compute instance for chaining calls.</returns> + ICompute WithKeepPortable(); + + /// <summary> + /// Executes given Java task on the grid projection. If task for given name has not been deployed yet, + /// then 'taskName' will be used as task class name to auto-deploy the task. + /// </summary> + /// <param name="taskName">Java task name</param> + /// <param name="taskArg">Optional argument of task execution, can be null.</param> + /// <returns>Task result.</returns> + /// <typeparam name="T">Type of task result.</typeparam> + T ExecuteJavaTask<T>(string taskName, object taskArg); + + /// <summary> + /// Executes given task on the grid projection. For step-by-step explanation of task execution process + /// refer to <see cref="IComputeTask{A,T,R}"/> documentation. + /// </summary> + /// <param name="task">Task to execute.</param> + /// <param name="taskArg">Optional task argument.</param> + /// <returns>Task result.</returns> + /// <typeparam name="TA">Argument type.</typeparam> + /// <typeparam name="T">Type of job result.</typeparam> + /// <typeparam name="TR">Type of reduce result.</typeparam> + [AsyncSupported] + TR Execute<TA, T, TR>(IComputeTask<TA, T, TR> task, TA taskArg); + + /// <summary> + /// Executes given task on the grid projection. For step-by-step explanation of task execution process + /// refer to <see cref="IComputeTask{A,T,R}"/> documentation. + /// </summary> + /// <param name="task">Task to execute.</param> + /// <returns>Task result.</returns> + /// <typeparam name="T">Type of job result.</typeparam> + /// <typeparam name="TR">Type of reduce result.</typeparam> + [AsyncSupported] + TR Execute<T, TR>(IComputeTask<T, TR> task); + + /// <summary> + /// Executes given task on the grid projection. For step-by-step explanation of task execution process + /// refer to <see cref="IComputeTask{A,T,R}"/> documentation. + /// </summary> + /// <param name="taskType">Task type.</param> + /// <param name="taskArg">Optional task argument.</param> + /// <returns>Task result.</returns> + /// <typeparam name="TA">Argument type.</typeparam> + /// <typeparam name="T">Type of job result.</typeparam> + /// <typeparam name="TR">Type of reduce result.</typeparam> + [AsyncSupported] + TR Execute<TA, T, TR>(Type taskType, TA taskArg); + + /// <summary> + /// Executes given task on the grid projection. For step-by-step explanation of task execution process + /// refer to <see cref="IComputeTask{A,T,R}"/> documentation. + /// </summary> + /// <param name="taskType">Task type.</param> + /// <returns>Task result.</returns> + /// <typeparam name="T">Type of job result.</typeparam> + /// <typeparam name="TR">Type of reduce result.</typeparam> + [AsyncSupported] + TR Execute<T, TR>(Type taskType); + + /// <summary> + /// Executes provided job on a node in this grid projection. The result of the + /// job execution is returned from the result closure. + /// </summary> + /// <param name="clo">Job to execute.</param> + /// <returns>Job result for this execution.</returns> + /// <typeparam name="TR">Type of job result.</typeparam> + [AsyncSupported] + TR Call<TR>(IComputeFunc<TR> clo); + + /// <summary> + /// Executes given job on the node where data for provided affinity key is located + /// (a.k.a. affinity co-location). + /// </summary> + /// <param name="cacheName">Name of the cache to use for affinity co-location.</param> + /// <param name="affinityKey">Affinity key.</param> + /// <param name="clo">Job to execute.</param> + /// <returns>Job result for this execution.</returns> + /// <typeparam name="TR">Type of job result.</typeparam> + [AsyncSupported] + TR AffinityCall<TR>(string cacheName, object affinityKey, IComputeFunc<TR> clo); + + /// <summary> + /// Executes collection of jobs on nodes within this grid projection. + /// </summary> + /// <param name="clos">Collection of jobs to execute.</param> + /// <param name="rdc">Reducer to reduce all job results into one individual return value.</param> + /// <returns>Reduced job result for this execution.</returns> + /// <typeparam name="TR1">Type of job result.</typeparam> + /// <typeparam name="TR2">Type of reduced result.</typeparam> + [AsyncSupported] + TR2 Call<TR1, TR2>(IEnumerable<IComputeFunc<TR1>> clos, IComputeReducer<TR1, TR2> rdc); + + /// <summary> + /// Executes collection of jobs on nodes within this grid projection. + /// </summary> + /// <param name="clos">Collection of jobs to execute.</param> + /// <returns>Collection of job results for this execution.</returns> + /// <typeparam name="TR">Type of job result.</typeparam> + [AsyncSupported] + ICollection<TR> Call<TR>(IEnumerable<IComputeFunc<TR>> clos); + + /// <summary> + /// Broadcasts given job to all nodes in grid projection. Every participating node will return a job result. + /// </summary> + /// <param name="clo">Job to broadcast to all projection nodes.</param> + /// <returns>Collection of results for this execution.</returns> + [AsyncSupported] + ICollection<TR> Broadcast<TR>(IComputeFunc<TR> clo); + + /// <summary> + /// Broadcasts given closure job with passed in argument to all nodes in grid projection. + /// Every participating node will return a job result. + /// </summary> + /// <param name="clo">Job to broadcast to all projection nodes.</param> + /// <param name="arg">Job closure argument.</param> + /// <returns>Collection of results for this execution.</returns> + /// <typeparam name="T">Type of argument.</typeparam> + /// <typeparam name="TR">Type of job result.</typeparam> + [AsyncSupported] + ICollection<TR> Broadcast<T, TR>(IComputeFunc<T, TR> clo, T arg); + + /// <summary> + /// Broadcasts given job to all nodes in grid projection. + /// </summary> + /// <param name="action">Job to broadcast to all projection nodes.</param> + [AsyncSupported] + void Broadcast(IComputeAction action); + + /// <summary> + /// Executes provided job on a node in this grid projection. + /// </summary> + /// <param name="action">Job to execute.</param> + [AsyncSupported] + void Run(IComputeAction action); + + /// <summary> + /// Executes given job on the node where data for provided affinity key is located + /// (a.k.a. affinity co-location). + /// </summary> + /// <param name="cacheName">Name of the cache to use for affinity co-location.</param> + /// <param name="affinityKey">Affinity key.</param> + /// <param name="action">Job to execute.</param> + [AsyncSupported] + void AffinityRun(string cacheName, object affinityKey, IComputeAction action); + + /// <summary> + /// Executes collection of jobs on Ignite nodes within this grid projection. + /// </summary> + /// <param name="actions">Jobs to execute.</param> + [AsyncSupported] + void Run(IEnumerable<IComputeAction> actions); + + /// <summary> + /// Executes provided closure job on a node in this grid projection. + /// </summary> + /// <param name="clo">Job to run.</param> + /// <param name="arg">Job argument.</param> + /// <returns>Job result for this execution.</returns> + /// <typeparam name="T">Type of argument.</typeparam> + /// <typeparam name="TR">Type of job result.</typeparam> + [AsyncSupported] + TR Apply<T, TR>(IComputeFunc<T, TR> clo, T arg); + + /// <summary> + /// Executes provided closure job on nodes within this grid projection. A new job is executed for + /// every argument in the passed in collection. The number of actual job executions will be + /// equal to size of the job arguments collection. + /// </summary> + /// <param name="clo">Job to run.</param> + /// <param name="args">Job arguments.</param> + /// <returns>Сollection of job results.</returns> + /// <typeparam name="T">Type of argument.</typeparam> + /// <typeparam name="TR">Type of job result.</typeparam> + [AsyncSupported] + ICollection<TR> Apply<T, TR>(IComputeFunc<T, TR> clo, IEnumerable<T> args); + + /// <summary> + /// Executes provided closure job on nodes within this grid projection. A new job is executed for + /// every argument in the passed in collection. The number of actual job executions will be + /// equal to size of the job arguments collection. The returned job results will be reduced + /// into an individual result by provided reducer. + /// </summary> + /// <param name="clo">Job to run.</param> + /// <param name="args">Job arguments.</param> + /// <param name="rdc">Reducer to reduce all job results into one individual return value.</param> + /// <returns>Reduced job result for this execution.</returns> + /// <typeparam name="T">Type of argument.</typeparam> + /// <typeparam name="TR1">Type of job result.</typeparam> + /// <typeparam name="TR2">Type of reduced result.</typeparam> + [AsyncSupported] + TR2 Apply<T, TR1, TR2>(IComputeFunc<T, TR1> clo, IEnumerable<T> args, IComputeReducer<TR1, TR2> rdc); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeFunc.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeFunc.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeFunc.cs new file mode 100644 index 0000000..4a43f11 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeFunc.cs @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + /// <summary> + /// Defines function having a single argument. + /// </summary> + public interface IComputeFunc<in T, out TR> + { + /// <summary> + /// Invoke function. + /// </summary> + /// <param name="arg">Argument.</param> + /// <returns>Result.</returns> + TR Invoke(T arg); + } + + /// <summary> + /// Defines function having no arguments. + /// </summary> + public interface IComputeFunc<out T> + { + /// <summary> + /// Invoke function. + /// </summary> + /// <returns>Result.</returns> + T Invoke(); + } + + /// <summary> + /// Defines a void function having no arguments. + /// </summary> + public interface IComputeAction + { + /// <summary> + /// Invokes action. + /// </summary> + void Invoke(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeJob.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeJob.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeJob.cs new file mode 100644 index 0000000..3b8ac60 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeJob.cs @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System.Collections.Generic; + using Apache.Ignite.Core.Resource; + + /// <summary> + /// Defines executable unit for <see cref="IComputeTask{A,T,R}"/>. Ignite task gets split into jobs + /// when <see cref="IComputeTask{A,T,R}.Map(IList{IClusterNode}, A)"/> method is called. This + /// method returns all jobs for the task mapped to their corresponding Ignite nodes for execution. + /// Grid will then serialize this jobs and send them to requested nodes for execution. + /// <para /> + /// Once job execution is complete, the return value will be sent back to parent task and will + /// be passed into + /// <see cref="IComputeTask{A,T,R}.Result(IComputeJobResult{T}, IList{IComputeJobResult{T}})"/> + /// method via <see cref="IComputeJobResult{T}"/> instance. + /// <para /> + /// Ignite job implementation can be injected with <see cref="IIgnite"/> using + /// <see cref="InstanceResourceAttribute"/> attribute. + /// </summary> + public interface IComputeJob<out T> + { + /// <summary> + /// Executes this job. + /// </summary> + /// <returns>Job execution result (possibly <c>null</c>). This result will be returned + /// in <see cref="IComputeJobResult{T}"/> object passed into + /// <see cref="IComputeTask{A,T,R}.Result(IComputeJobResult{T}, IList{IComputeJobResult{T}})"/> + /// on caller node.</returns> + T Execute(); + + /// <summary> + /// This method is called when system detects that completion of this + /// job can no longer alter the overall outcome (for example, when parent task + /// has already reduced the results). + /// <para /> + /// Note that job cancellation is only a hint, and it is really up to the actual job + /// instance to gracefully finish execution and exit. + /// </summary> + void Cancel(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeJobResult.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeJobResult.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeJobResult.cs new file mode 100644 index 0000000..5891fd7 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeJobResult.cs @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System; + using System.Collections.Generic; + + /// <summary> + /// Job execution result which gets passed to + /// <see cref="IComputeTask{A,T,R}.Result(IComputeJobResult{T}, IList{IComputeJobResult{T}})"/> + /// method. + /// </summary> + public interface IComputeJobResult<out T> + { + /// <summary> + /// Gets data returned by remote job if it didn't fail. This data is the + /// object returned from <see cref="IComputeJob{T}.Execute()"/> method. + /// <para /> + /// Note that if task is annotated with <see cref="ComputeTaskNoResultCacheAttribute"/> + /// attribute, then job results will not be cached and will be available only in + /// <see cref="IComputeTask{A,T,R}.Result(IComputeJobResult{T}, IList{IComputeJobResult{T}})"/> + /// method for every individual job, but not in + /// <see cref="IComputeTask{A,T,R}.Reduce(IList{IComputeJobResult{T}})"/> method. + /// + /// </summary> + /// <returns>Data returned by job.</returns> + T Data(); + + /// <summary> + /// Gets local instance of remote job produced this result. + /// </summary> + /// <returns></returns> + IComputeJob<T> Job(); + + /// <summary> + /// Gets exception produced by execution of remote job, or <c>null</c> if no + /// exception was produced. + /// </summary> + /// <returns>Exception or <c>null</c> in case of success.</returns> + Exception Exception(); + + /// <summary> + /// ID of the node where actual job execution occurred. + /// </summary> + Guid NodeId + { + get; + } + + /// <summary> + /// Whether the job was cancelled. + /// </summary> + bool Cancelled + { + get; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeReducer.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeReducer.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeReducer.cs new file mode 100644 index 0000000..46dcbd9 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeReducer.cs @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + /// <summary> + /// Compute reducer which is capable of result collecting and reducing. + /// </summary> + public interface IComputeReducer<in TR1, out TR2> + { + /// <summary> + /// Collect closure execution result. + /// </summary> + /// <param name="res">Result.</param> + /// <returns><c>True</c> to continue collecting results until all closures are finished, + /// <c>false</c> to start reducing.</returns> + bool Collect(TR1 res); + + /// <summary> + /// Reduce closure execution results collected earlier. + /// </summary> + /// <returns>Reduce result.</returns> + TR2 Reduce(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeTask.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeTask.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeTask.cs new file mode 100644 index 0000000..21b6c48 --- /dev/null +++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Compute/IComputeTask.cs @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Compute +{ + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using Apache.Ignite.Core.Cluster; + + /// <summary> + /// Ignite task interface defines a task that can be executed on the grid. Ignite task + /// is responsible for splitting business logic into multiple Ignite jobs, receiving + /// results from individual Ignite jobs executing on remote nodes, and reducing + /// (aggregating) received jobs' results into final Ignite task result. + /// <para /> + /// Upon request to execute a task, the system will do the following: + /// <list type="bullet"> + /// <item> + /// <description>Inject annotated resources into task instance.</description> + /// </item> + /// <item> + /// <description>Apply <see cref="IComputeTask{A,T,R}.Map(IList{IClusterNode}, TA)"/>. + /// This method is responsible for splitting business logic into multiple jobs + /// (units of execution) and mapping them to Ignite nodes.</description> + /// </item> + /// <item> + /// <description>System will send mapped Ignite jobs to their respective nodes.</description> + /// </item> + /// <item> + /// <description>Once job execution results become available method + /// <see cref="IComputeTask{A,T,R}.Result(IComputeJobResult{T}, IList{IComputeJobResult{T}})"/> + /// will be called for ech received job result. The policy returned by this method will + /// determine the way task reacts to every job result. + /// <para /> + /// If <see cref="ComputeJobResultPolicy.Wait"/> is returned, task will continue to wait + /// for other job results. If this result is the last job result, then reduce phase will be + /// started. + /// <para /> + /// If <see cref="ComputeJobResultPolicy.Reduce"/> is returned, reduce phase will be started + /// right away without waiting for other jobs completion (all remaining jobs will receive cancel + /// request). + /// <para /> + /// If <see cref="ComputeJobResultPolicy.Failover"/> is returned, job will be failed over to + /// another node for execution. Note that if you use <see cref="ComputeTaskAdapter{A,T,R}"/>, it will + /// automatically fail jobs to another node for 2 well-known failure cases: 1) job has failed to due + /// to node crash (in this case <see cref="IComputeJobResult{T}.Exception()"/> will return + /// <see cref="ClusterTopologyException"/>); 2) job execution was rejected, i.e. remote node + /// has cancelled job before it got a chance to execute, while it still was on the waiting list. + /// (in this case <see cref="IComputeJobResult{T}.Exception()"/> will return + /// <see cref="ComputeExecutionRejectedException"/>). + /// </description> + /// </item> + /// <item> + /// <description>Once all results are received or + /// <see cref="IComputeTask{A,T,R}.Result(IComputeJobResult{T}, IList{IComputeJobResult{T}})"/> + /// method returned <see cref="ComputeJobResultPolicy.Reduce"/> policy, method + /// <see cref="IComputeTask{A,T,R}.Reduce(IList{IComputeJobResult{T}})"/> + /// is called to aggregate received results into one final result. Once this method is finished the + /// execution of the Ignite task is complete. This result will be returned to the user through future. + /// </description> + /// </item> + /// </list> + /// </summary> + /// <typeparam name="TA">Argument type.</typeparam> + /// <typeparam name="T">Type of job result.</typeparam> + /// <typeparam name="TR">Type of reduce result.</typeparam> + public interface IComputeTask<in TA, T, out TR> + { + /// <summary> + /// This method is called to map or split Ignite task into multiple Ignite jobs. This is the + /// first method that gets called when task execution starts. + /// </summary> + /// <param name="subgrid">Nodes available for this task execution. Note that order of nodes is + /// guaranteed to be randomized by container. This ensures that every time you simply iterate + /// through Ignite nodes, the order of nodes will be random which over time should result into + /// all nodes being used equally.</param> + /// <param name="arg">Task execution argument. Can be <c>null</c>. This is the same argument + /// as the one passed into <c>ICompute.Execute()</c> methods.</param> + /// <returns>Map of Ignite jobs assigned to subgrid node. If <c>null</c> or empty map is returned, + /// exception will be thrown.</returns> + IDictionary<IComputeJob<T>, IClusterNode> Map(IList<IClusterNode> subgrid, TA arg); + + /// <summary> + /// Asynchronous callback invoked every time a result from remote execution is + /// received. It is ultimately upto this method to return a policy based + /// on which the system will either wait for more results, reduce results + /// received so far, or failover this job to another node. See + /// <see cref="ComputeJobResultPolicy"/> for more information. + /// </summary> + /// <param name="res">Received remote Ignite executable result.</param> + /// <param name="rcvd">All previously received results. Note that if task class has + /// <see cref="ComputeTaskNoResultCacheAttribute"/> attribute, then this list will be empty.</param> + /// <returns>Result policy that dictates how to process further upcoming job results.</returns> + ComputeJobResultPolicy Result(IComputeJobResult<T> res, IList<IComputeJobResult<T>> rcvd); + + /// <summary> + /// Reduces (or aggregates) results received so far into one compound result to be returned to + /// caller via future. + /// <para /> + /// Note, that if some jobs did not succeed and could not be failed over then the list of + /// results passed into this method will include the failed results. Otherwise, failed + /// results will not be in the list. + /// </summary> + /// <param name="results">Received job results. Note that if task class has + /// <see cref="ComputeTaskNoResultCacheAttribute"/> attribute, then this list will be empty.</param> + /// <returns>Task result constructed from results of remote executions.</returns> + TR Reduce(IList<IComputeJobResult<T>> results); + } + + /// <summary> + /// IComputeTask without an argument. + /// </summary> + [SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")] + public interface IComputeTask<T, out TR> : IComputeTask<object, T, TR> + { + // No-op. + } +}
