You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/09/21 16:27:43 UTC
[47/52] [partial] ignite git commit: IGNITE-1513: Moved .Net.
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Compute/ICompute.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Compute/ICompute.cs b/modules/platform/dotnet/Apache.Ignite.Core/Compute/ICompute.cs
new file mode 100644
index 0000000..c124f84
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Compute/ICompute.cs
@@ -0,0 +1,271 @@
+/*
+ * 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.GetCompute"/> 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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeFunc.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeFunc.cs b/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeFunc.cs
new file mode 100644
index 0000000..4a43f11
--- /dev/null
+++ b/modules/platform/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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeJob.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeJob.cs b/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeJob.cs
new file mode 100644
index 0000000..3b8ac60
--- /dev/null
+++ b/modules/platform/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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeJobResult.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeJobResult.cs b/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeJobResult.cs
new file mode 100644
index 0000000..5891fd7
--- /dev/null
+++ b/modules/platform/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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeReducer.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeReducer.cs b/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeReducer.cs
new file mode 100644
index 0000000..46dcbd9
--- /dev/null
+++ b/modules/platform/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/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeTask.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeTask.cs b/modules/platform/dotnet/Apache.Ignite.Core/Compute/IComputeTask.cs
new file mode 100644
index 0000000..21b6c48
--- /dev/null
+++ b/modules/platform/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.
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Datastream/IDataStreamer.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Datastream/IDataStreamer.cs b/modules/platform/dotnet/Apache.Ignite.Core/Datastream/IDataStreamer.cs
new file mode 100644
index 0000000..2713040
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Datastream/IDataStreamer.cs
@@ -0,0 +1,206 @@
+/*
+ * 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.Datastream
+{
+ using System;
+ using System.Collections.Generic;
+ using Apache.Ignite.Core.Cache.Store;
+ using Apache.Ignite.Core.Common;
+
+ /// <summary>
+ /// Data streamer is responsible for loading external data into cache. It achieves it by
+ /// properly buffering updates and properly mapping keys to nodes responsible for the data
+ /// to make sure that there is the least amount of data movement possible and optimal
+ /// network and memory utilization.
+ /// <para />
+ /// Note that streamer will load data concurrently by multiple internal threads, so the
+ /// data may get to remote nodes in different order from which it was added to
+ /// the streamer.
+ /// <para />
+ /// Also note that <c>IDataStreamer</c> is not the only way to load data into cache.
+ /// Alternatively you can use
+ /// <see cref="ICacheStore.LoadCache(Action{object, object}, object[])"/>
+ /// method to load data from underlying data store. You can also use standard cache
+ /// <c>put</c> and <c>putAll</c> operations as well, but they most likely will not perform
+ /// as well as this class for loading data. And finally, data can be loaded from underlying
+ /// data store on demand, whenever it is accessed - for this no explicit data loading step
+ /// is needed.
+ /// <para />
+ /// <c>IDataStreamer</c> supports the following configuration properties:
+ /// <list type="bullet">
+ /// <item>
+ /// <term>PerNodeBufferSize</term>
+ /// <description>When entries are added to data streamer they are not sent to Ignite
+ /// right away and are buffered internally for better performance and network utilization.
+ /// This setting controls the size of internal per-node buffer before buffered data is sent to
+ /// remote node. Default value is 1024.</description>
+ /// </item>
+ /// <item>
+ /// <term>PerNodeParallelOperations</term>
+ /// <description>Sometimes data may be added to the data streamer faster than it can be put
+ /// in cache. In this case, new buffered load messages are sent to remote nodes before
+ /// responses from previous ones are received. This could cause unlimited heap memory
+ /// utilization growth on local and remote nodes. To control memory utilization, this
+ /// setting limits maximum allowed number of parallel buffered load messages that are
+ /// being processed on remote nodes. If this number is exceeded, then data streamer add/remove
+ /// methods will block to control memory utilization. Default value is 16.</description>
+ /// </item>
+ /// <item>
+ /// <term>AutoFlushFrequency</term>
+ /// <description>Automatic flush frequency in milliseconds. Essentially, this is the time
+ /// after which the streamer will make an attempt to submit all data added so far to remote
+ /// nodes. Note that there is no guarantee that data will be delivered after this concrete
+ /// attempt (e.g., it can fail when topology is changing), but it won't be lost anyway.
+ /// Disabled by default (default value is <c>0</c>).</description>
+ /// </item>
+ /// <item>
+ /// <term>Isolated</term>
+ /// <description>Defines if data streamer will assume that there are no other concurrent
+ /// updates and allow data streamer choose most optimal concurrent implementation. Default value
+ /// is <c>false</c>.</description>
+ /// </item>
+ /// </list>
+ /// <para/>
+ /// All members are thread-safe and may be used concurrently from multiple threads.
+ /// </summary>
+ public interface IDataStreamer<TK, TV> : IDisposable
+ {
+ /// <summary>
+ /// Name of the cache to load data to.
+ /// </summary>
+ string CacheName { get; }
+
+ /// <summary>
+ /// Flag value indicating that this data streamer assumes that there could be concurrent updates to the cache.
+ /// <para />
+ /// Default is <code>false</code>.
+ /// </summary>
+ bool AllowOverwrite { get; set; }
+
+ /// <summary>
+ /// Flag indicating that write-through behavior should be disabled for data loading.
+ /// <para />
+ /// Default is <code>false</code>.
+ /// </summary>
+ bool SkipStore { get; set; }
+
+ /// <summary>
+ /// Size of per node key-value pairs buffer.
+ /// <para />
+ /// Setter must be called before any add/remove operation.
+ /// <para />
+ /// Default is <code>1024</code>.
+ /// </summary>
+ int PerNodeBufferSize { get; set; }
+
+ /// <summary>
+ /// Maximum number of parallel load operations for a single node.
+ /// <para />
+ /// Setter must be called before any add/remove operation.
+ /// <para />
+ /// Default is <code>16</code>.
+ /// </summary>
+ int PerNodeParallelOperations { get; set; }
+
+ /// <summary>
+ /// Automatic flush frequency in milliseconds. Essentially, this is the time after which the
+ /// streamer will make an attempt to submit all data added so far to remote nodes.
+ /// Note that there is no guarantee that data will be delivered after this concrete
+ /// attempt (e.g., it can fail when topology is changing), but it won't be lost anyway.
+ /// <para />
+ /// If set to <code>0</code>, automatic flush is disabled.
+ /// <para />
+ /// Default is <code>0</code> (disabled).
+ /// </summary>
+ long AutoFlushFrequency { get; set; }
+
+ /// <summary>
+ /// Gets future for this loading process. This future completes whenever method
+ /// <see cref="IDataStreamer{K,V}.Close(bool)"/> completes.
+ /// </summary>
+ IFuture Future { get; }
+
+ /// <summary>
+ /// Gets or sets custom stream receiver.
+ /// </summary>
+ IStreamReceiver<TK, TV> Receiver { get; set; }
+
+ /// <summary>
+ /// Adds single key-value pair for loading. Passing <c>null</c> as value will be
+ /// interpreted as removal.
+ /// </summary>
+ /// <param name="key">Key.</param>
+ /// <param name="val">Value.</param>
+ /// <returns>Future for this operation.</returns>
+ IFuture AddData(TK key, TV val);
+
+ /// <summary>
+ /// Adds single key-value pair for loading. Passing <c>null</c> as pair's value will
+ /// be interpreted as removal.
+ /// </summary>
+ /// <param name="pair">Key-value pair.</param>
+ /// <returns>Future for this operation.</returns>
+ IFuture AddData(KeyValuePair<TK, TV> pair);
+
+ /// <summary>
+ /// Adds collection of key-value pairs for loading.
+ /// </summary>
+ /// <param name="entries">Entries.</param>
+ /// <returns>Future for this operation.</returns>
+ IFuture AddData(ICollection<KeyValuePair<TK, TV>> entries);
+
+ /// <summary>
+ /// Adds key for removal.
+ /// </summary>
+ /// <param name="key">Key.</param>
+ /// <returns>Future for this operation.</returns>
+ IFuture RemoveData(TK key);
+
+ /// <summary>
+ /// Makes an attempt to load remaining data. This method is mostly similar to
+ /// <see cref="IDataStreamer{K,V}.Flush()"/> with the difference that it won't wait and
+ /// will exit immediately.
+ /// </summary>
+ void TryFlush();
+
+ /// <summary>
+ /// Loads any remaining data, but doesn't close the streamer. Data can be still added after
+ /// flush is finished. This method blocks and doesn't allow to add any data until all data
+ /// is loaded.
+ /// </summary>
+ void Flush();
+
+ /// <summary>
+ /// Closes this streamer optionally loading any remaining data.
+ /// </summary>
+ /// <param name="cancel">Whether to cancel ongoing loading operations. When set to <c>true</c>
+ /// there is not guarantees what data will be actually loaded to cache.</param>
+ void Close(bool cancel);
+
+ /// <summary>
+ /// Gets streamer instance with portable mode enabled, changing key and/or value types if necessary.
+ /// In portable mode stream receiver gets data in portable format.
+ /// You can only change key/value types when transitioning from non-portable to portable streamer;
+ /// Changing type of portable streamer is not allowed and will throw an <see cref="InvalidOperationException"/>
+ /// </summary>
+ /// <typeparam name="TK1">Key type in portable mode.</typeparam>
+ /// <typeparam name="TV1">Value type in protable mode.</typeparam>
+ /// <returns>Streamer instance with portable mode enabled.</returns>
+ IDataStreamer<TK1, TV1> WithKeepPortable<TK1, TV1>();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Datastream/IStreamReceiver.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Datastream/IStreamReceiver.cs b/modules/platform/dotnet/Apache.Ignite.Core/Datastream/IStreamReceiver.cs
new file mode 100644
index 0000000..d75dc54
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Datastream/IStreamReceiver.cs
@@ -0,0 +1,38 @@
+/*
+ * 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.Datastream
+{
+ using System.Collections.Generic;
+ using Apache.Ignite.Core.Cache;
+
+ /// <summary>
+ /// Updates cache with batch of entries.
+ /// Usually it is enough to configure <see cref="IDataStreamer{K,V}.AllowOverwrite" /> property and appropriate
+ /// internal cache receiver will be chosen automatically. But in some cases custom implementation may help
+ /// to achieve better performance.
+ /// </summary>
+ public interface IStreamReceiver<TK, TV>
+ {
+ /// <summary>
+ /// Updates cache with batch of entries.
+ /// </summary>
+ /// <param name="cache">Cache.</param>
+ /// <param name="entries">Entries.</param>
+ void Receive(ICache<TK, TV> cache, ICollection<ICacheEntry<TK, TV>> entries);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Datastream/StreamTransformer.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Datastream/StreamTransformer.cs b/modules/platform/dotnet/Apache.Ignite.Core/Datastream/StreamTransformer.cs
new file mode 100644
index 0000000..0398342
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Datastream/StreamTransformer.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.Datastream
+{
+ using System.Collections.Generic;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Impl.Common;
+ using Apache.Ignite.Core.Impl.Datastream;
+ using Apache.Ignite.Core.Impl.Portable;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Convenience adapter to transform update existing values in streaming cache
+ /// based on the previously cached value.
+ /// </summary>
+ /// <typeparam name="TK">Key type.</typeparam>
+ /// <typeparam name="TV">Value type.</typeparam>
+ /// <typeparam name="TA">The type of the processor argument.</typeparam>
+ /// <typeparam name="TR">The type of the processor result.</typeparam>
+ public sealed class StreamTransformer<TK, TV, TA, TR> : IStreamReceiver<TK, TV>,
+ IPortableWriteAware
+ {
+ /** Entry processor. */
+ private readonly ICacheEntryProcessor<TK, TV, TA, TR> _proc;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="StreamTransformer{K, V, A, R}"/> class.
+ /// </summary>
+ /// <param name="proc">Entry processor.</param>
+ public StreamTransformer(ICacheEntryProcessor<TK, TV, TA, TR> proc)
+ {
+ IgniteArgumentCheck.NotNull(proc, "proc");
+
+ _proc = proc;
+ }
+
+ /** <inheritdoc /> */
+ public void Receive(ICache<TK, TV> cache, ICollection<ICacheEntry<TK, TV>> entries)
+ {
+ var keys = new List<TK>(entries.Count);
+
+ foreach (var entry in entries)
+ keys.Add(entry.Key);
+
+ cache.InvokeAll(keys, _proc, default(TA));
+ }
+
+ /** <inheritdoc /> */
+ void IPortableWriteAware.WritePortable(IPortableWriter writer)
+ {
+ var w = (PortableWriterImpl)writer;
+
+ w.WriteByte(StreamReceiverHolder.RcvTransformer);
+
+ PortableUtils.WritePortableOrSerializable(w, _proc);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Datastream/StreamVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Datastream/StreamVisitor.cs b/modules/platform/dotnet/Apache.Ignite.Core/Datastream/StreamVisitor.cs
new file mode 100644
index 0000000..5d155d7
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Datastream/StreamVisitor.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.Datastream
+{
+ using System;
+ using System.Collections.Generic;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Impl.Common;
+
+ /// <summary>
+ /// Convenience adapter to visit every key-value tuple in the stream.
+ /// Note that the visitor does not update the cache.
+ /// </summary>
+ /// <typeparam name="TK">The type of the cache key.</typeparam>
+ /// <typeparam name="TV">The type of the cache value.</typeparam>
+ [Serializable]
+ public sealed class StreamVisitor<TK, TV> : IStreamReceiver<TK, TV>
+ {
+ /** Visitor action */
+ private readonly Action<ICache<TK, TV>, ICacheEntry<TK, TV>> _action;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="StreamVisitor{K, V}"/> class.
+ /// </summary>
+ /// <param name="action">The action to be called on each stream entry.</param>
+ public StreamVisitor(Action<ICache<TK, TV>, ICacheEntry<TK, TV>> action)
+ {
+ IgniteArgumentCheck.NotNull(action, "action");
+
+ _action = action;
+ }
+
+ /** <inheritdoc /> */
+ public void Receive(ICache<TK, TV> cache, ICollection<ICacheEntry<TK, TV>> entries)
+ {
+ foreach (var entry in entries)
+ _action(cache, entry);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheEvent.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheEvent.cs b/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheEvent.cs
new file mode 100644
index 0000000..ff5084b
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheEvent.cs
@@ -0,0 +1,176 @@
+/*
+ * 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.Events
+{
+ using System;
+ using Apache.Ignite.Core.Cluster;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// In-memory database (cache) event.
+ /// </summary>
+ public sealed class CacheEvent : EventBase
+ {
+ /** */
+ private readonly string _cacheName;
+
+ /** */
+ private readonly int _partition;
+
+ /** */
+ private readonly bool _isNear;
+
+ /** */
+ private readonly IClusterNode _eventNode;
+
+ /** */
+ private readonly object _key;
+
+ /** */
+ private readonly IgniteGuid _xid;
+
+ /** */
+ private readonly object _lockId;
+
+ /** */
+ private readonly object _newValue;
+
+ /** */
+ private readonly object _oldValue;
+
+ /** */
+ private readonly bool _hasOldValue;
+
+ /** */
+ private readonly bool _hasNewValue;
+
+ /** */
+ private readonly Guid _subjectId;
+
+ /** */
+ private readonly string _closureClassName;
+
+ /** */
+ private readonly string _taskName;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="r">The reader to read data from.</param>
+ internal CacheEvent(IPortableRawReader r) : base(r)
+ {
+ _cacheName = r.ReadString();
+ _partition = r.ReadInt();
+ _isNear = r.ReadBoolean();
+ _eventNode = ReadNode(r);
+ _key = r.ReadObject<object>();
+ _xid = IgniteGuid.ReadPortable(r);
+ _lockId = r.ReadObject<object>();
+ _newValue = r.ReadObject<object>();
+ _oldValue = r.ReadObject<object>();
+ _hasOldValue = r.ReadBoolean();
+ _hasNewValue = r.ReadBoolean();
+ _subjectId = r.ReadGuid() ?? Guid.Empty;
+ _closureClassName = r.ReadString();
+ _taskName = r.ReadString();
+ }
+
+ /// <summary>
+ /// Gets cache name.
+ /// </summary>
+ public string CacheName { get { return _cacheName; } }
+
+ /// <summary>
+ /// Gets partition for the event which is the partition the key belongs to.
+ /// </summary>
+ public int Partition { get { return _partition; } }
+
+ /// <summary>
+ /// Gets flag indicating whether event happened on near or partitioned cache.
+ /// </summary>
+ public bool IsNear { get { return _isNear; } }
+
+ /// <summary>
+ /// Gets node which initiated cache operation or null if that node is not available.
+ /// </summary>
+ public IClusterNode EventNode { get { return _eventNode; } }
+
+ /// <summary>
+ /// Gets cache entry associated with event.
+ /// </summary>
+ public object Key { get { return _key; } }
+
+ /// <summary>
+ /// ID of surrounding cache cache transaction or null if there is no surrounding transaction.
+ /// </summary>
+ public IgniteGuid Xid { get { return _xid; } }
+
+ /// <summary>
+ /// ID of the lock if held or null if no lock held.
+ /// </summary>
+ public object LockId { get { return _lockId; } }
+
+ /// <summary>
+ /// Gets new value for this event.
+ /// </summary>
+ public object NewValue { get { return _newValue; } }
+
+ /// <summary>
+ /// Gets old value associated with this event.
+ /// </summary>
+ public object OldValue { get { return _oldValue; } }
+
+ /// <summary>
+ /// Gets flag indicating whether cache entry has old value in case if we only have old value in serialized form
+ /// in which case <see cref="OldValue" /> will return null.
+ /// </summary>
+ public bool HasOldValue { get { return _hasOldValue; } }
+
+ /// <summary>
+ /// Gets flag indicating whether cache entry has new value in case if we only have new value in serialized form
+ /// in which case <see cref="NewValue" /> will return null.
+ /// </summary>
+ public bool HasNewValue { get { return _hasNewValue; } }
+
+ /// <summary>
+ /// Gets security subject ID initiated this cache event, if available. This property is available only for <see
+ /// cref="EventType.EvtCacheObjectPut" />, <see cref="EventType.EvtCacheObjectRemoved" /> and <see
+ /// cref="EventType.EvtCacheObjectRead" /> cache events. Subject ID will be set either to nodeId initiated
+ /// cache update or read or client ID initiated cache update or read.
+ /// </summary>
+ public Guid SubjectId { get { return _subjectId; } }
+
+ /// <summary>
+ /// Gets closure class name (applicable only for TRANSFORM operations).
+ /// </summary>
+ public string ClosureClassName { get { return _closureClassName; } }
+
+ /// <summary>
+ /// Gets task name if cache event was caused by an operation initiated within task execution.
+ /// </summary>
+ public string TaskName { get { return _taskName; } }
+
+ /** <inheritDoc /> */
+ public override string ToShortString()
+ {
+ return string.Format("{0}: IsNear={1}, Key={2}, HasNewValue={3}, HasOldValue={4}, NodeId={5}", Name,
+ _isNear, _key, HasNewValue, HasOldValue, Node.Id);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheQueryExecutedEvent.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheQueryExecutedEvent.cs b/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheQueryExecutedEvent.cs
new file mode 100644
index 0000000..8443c68
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheQueryExecutedEvent.cs
@@ -0,0 +1,97 @@
+/*
+ * 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.Events
+{
+ using System;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Cache query execution event.
+ /// </summary>
+ public sealed class CacheQueryExecutedEvent : EventBase
+ {
+ /** */
+ private readonly string _queryType;
+
+ /** */
+ private readonly string _cacheName;
+
+ /** */
+ private readonly string _className;
+
+ /** */
+ private readonly string _clause;
+
+ /** */
+ private readonly Guid _subjectId;
+
+ /** */
+ private readonly string _taskName;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="r">The reader to read data from.</param>
+ internal CacheQueryExecutedEvent(IPortableRawReader r) : base(r)
+ {
+ _queryType = r.ReadString();
+ _cacheName = r.ReadString();
+ _className = r.ReadString();
+ _clause = r.ReadString();
+ _subjectId = r.ReadGuid() ?? Guid.Empty;
+ _taskName = r.ReadString();
+ }
+
+ /// <summary>
+ /// Gets query type.
+ /// </summary>
+ public string QueryType { get { return _queryType; } }
+
+ /// <summary>
+ /// Gets cache name on which query was executed.
+ /// </summary>
+ public string CacheName { get { return _cacheName; } }
+
+ /// <summary>
+ /// Gets queried class name. Applicable for SQL and full text queries.
+ /// </summary>
+ public string ClassName { get { return _className; } }
+
+ /// <summary>
+ /// Gets query clause. Applicable for SQL, SQL fields and full text queries.
+ /// </summary>
+ public string Clause { get { return _clause; } }
+
+ /// <summary>
+ /// Gets security subject ID.
+ /// </summary>
+ public Guid SubjectId { get { return _subjectId; } }
+
+ /// <summary>
+ /// Gets the name of the task that executed the query (if any).
+ /// </summary>
+ public string TaskName { get { return _taskName; } }
+
+ /** <inheritDoc /> */
+ public override string ToShortString()
+ {
+ return string.Format("{0}: QueryType={1}, CacheName={2}, ClassName={3}, Clause={4}, SubjectId={5}, " +
+ "TaskName={6}", Name, QueryType, CacheName, ClassName, Clause, SubjectId, TaskName);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheQueryReadEvent.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheQueryReadEvent.cs b/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheQueryReadEvent.cs
new file mode 100644
index 0000000..7338eab
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheQueryReadEvent.cs
@@ -0,0 +1,134 @@
+/*
+ * 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.Events
+{
+ using System;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Cache query read event.
+ /// </summary>
+ public sealed class CacheQueryReadEvent : EventBase
+ {
+ /** */
+ private readonly string _queryType;
+
+ /** */
+ private readonly string _cacheName;
+
+ /** */
+ private readonly string _className;
+
+ /** */
+ private readonly string _clause;
+
+ /** */
+ private readonly Guid _subjectId;
+
+ /** */
+ private readonly string _taskName;
+
+ /** */
+ private readonly object _key;
+
+ /** */
+ private readonly object _value;
+
+ /** */
+ private readonly object _oldValue;
+
+ /** */
+ private readonly object _row;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="r">The reader to read data from.</param>
+ internal CacheQueryReadEvent(IPortableRawReader r) : base(r)
+ {
+ _queryType = r.ReadString();
+ _cacheName = r.ReadString();
+ _className = r.ReadString();
+ _clause = r.ReadString();
+ _subjectId = r.ReadGuid() ?? Guid.Empty;
+ _taskName = r.ReadString();
+ _key = r.ReadObject<object>();
+ _value = r.ReadObject<object>();
+ _oldValue = r.ReadObject<object>();
+ _row = r.ReadObject<object>();
+ }
+
+ /// <summary>
+ /// Gets query type.
+ /// </summary>
+ public string QueryType { get { return _queryType; } }
+
+ /// <summary>
+ /// Gets cache name on which query was executed.
+ /// </summary>
+ public string CacheName { get { return _cacheName; } }
+
+ /// <summary>
+ /// Gets queried class name. Applicable for SQL and full text queries.
+ /// </summary>
+ public string ClassName { get { return _className; } }
+
+ /// <summary>
+ /// Gets query clause. Applicable for SQL, SQL fields and full text queries.
+ /// </summary>
+ public string Clause { get { return _clause; } }
+
+ /// <summary>
+ /// Gets security subject ID.
+ /// </summary>
+ public Guid SubjectId { get { return _subjectId; } }
+
+ /// <summary>
+ /// Gets the name of the task that executed the query (if any).
+ /// </summary>
+ public string TaskName { get { return _taskName; } }
+
+ /// <summary>
+ /// Gets read entry key.
+ /// </summary>
+ public object Key { get { return _key; } }
+
+ /// <summary>
+ /// Gets read entry value.
+ /// </summary>
+ public object Value { get { return _value; } }
+
+ /// <summary>
+ /// Gets read entry old value (applicable for continuous queries).
+ /// </summary>
+ public object OldValue { get { return _oldValue; } }
+
+ /// <summary>
+ /// Gets read results set row.
+ /// </summary>
+ public object Row { get { return _row; } }
+
+ /** <inheritDoc /> */
+ public override string ToShortString()
+ {
+ return string.Format("{0}: QueryType={1}, CacheName={2}, ClassName={3}, Clause={4}, SubjectId={5}, " +
+ "TaskName={6}, Key={7}, Value={8}, OldValue={9}, Row={10}", Name, QueryType,
+ CacheName, ClassName, Clause, SubjectId, TaskName, Key, Value, OldValue, Row);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheRebalancingEvent.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheRebalancingEvent.cs b/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheRebalancingEvent.cs
new file mode 100644
index 0000000..656550a
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Events/CacheRebalancingEvent.cs
@@ -0,0 +1,98 @@
+/*
+ * 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.Events
+{
+ using Apache.Ignite.Core.Cluster;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// In-memory database (cache) rebalancing event. Rebalance event happens every time there is a change
+ /// </summary>
+ public sealed class CacheRebalancingEvent : EventBase
+ {
+ /** */
+ private readonly string _cacheName;
+
+ /** */
+ private readonly int _partition;
+
+ /** */
+ private readonly IClusterNode _discoveryNode;
+
+ /** */
+ private readonly int _discoveryEventType;
+
+ /** */
+ private readonly string _discoveryEventName;
+
+ /** */
+ private readonly long _discoveryTimestamp;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="r">The reader to read data from.</param>
+ internal CacheRebalancingEvent(IPortableRawReader r) : base(r)
+ {
+ _cacheName = r.ReadString();
+ _partition = r.ReadInt();
+ _discoveryNode = ReadNode(r);
+ _discoveryEventType = r.ReadInt();
+ _discoveryEventName = r.ReadString();
+ _discoveryTimestamp = r.ReadLong();
+ }
+
+ /// <summary>
+ /// Gets cache name.
+ /// </summary>
+ public string CacheName { get { return _cacheName; } }
+
+ /// <summary>
+ /// Gets partition for the event.
+ /// </summary>
+ public int Partition { get { return _partition; } }
+
+ /// <summary>
+ /// Gets shadow of the node that triggered this rebalancing event.
+ /// </summary>
+ public IClusterNode DiscoveryNode { get { return _discoveryNode; } }
+
+ /// <summary>
+ /// Gets type of discovery event that triggered this rebalancing event.
+ /// </summary>
+ public int DiscoveryEventType { get { return _discoveryEventType; } }
+
+ /// <summary>
+ /// Gets name of discovery event that triggered this rebalancing event.
+ /// </summary>
+ public string DiscoveryEventName { get { return _discoveryEventName; } }
+
+ /// <summary>
+ /// Gets timestamp of discovery event that caused this rebalancing event.
+ /// </summary>
+ public long DiscoveryTimestamp { get { return _discoveryTimestamp; } }
+
+ /** <inheritDoc /> */
+ public override string ToShortString()
+ {
+ return string.Format("{0}: CacheName={1}, Partition={2}, DiscoveryNode={3}, DiscoveryEventType={4}, " +
+ "DiscoveryEventName={5}, DiscoveryTimestamp={6}", Name, CacheName, Partition,
+ DiscoveryNode, DiscoveryEventType, DiscoveryEventName, DiscoveryTimestamp);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Events/CheckpointEvent.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Events/CheckpointEvent.cs b/modules/platform/dotnet/Apache.Ignite.Core/Events/CheckpointEvent.cs
new file mode 100644
index 0000000..7b7ea59
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Events/CheckpointEvent.cs
@@ -0,0 +1,50 @@
+/*
+ * 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.Events
+{
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Grid checkpoint event.
+ /// </summary>
+ public sealed class CheckpointEvent : EventBase
+ {
+ /** */
+ private readonly string _key;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="r">The reader to read data from.</param>
+ internal CheckpointEvent(IPortableRawReader r) : base(r)
+ {
+ _key = r.ReadString();
+ }
+
+ /// <summary>
+ /// Gets checkpoint key associated with this event.
+ /// </summary>
+ public string Key { get { return _key; } }
+
+ /** <inheritDoc /> */
+ public override string ToShortString()
+ {
+ return string.Format("{0}: Key={1}", Name, Key);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Events/DiscoveryEvent.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Events/DiscoveryEvent.cs b/modules/platform/dotnet/Apache.Ignite.Core/Events/DiscoveryEvent.cs
new file mode 100644
index 0000000..5b5443c
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Events/DiscoveryEvent.cs
@@ -0,0 +1,80 @@
+/*
+ * 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.Events
+{
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using Apache.Ignite.Core.Cluster;
+ using Apache.Ignite.Core.Impl;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Grid discovery event.
+ /// </summary>
+ public sealed class DiscoveryEvent : EventBase
+ {
+ /** */
+ private readonly IClusterNode _eventNode;
+
+ /** */
+ private readonly long _topologyVersion;
+
+ /** */
+ private readonly ReadOnlyCollection<IClusterNode> _topologyNodes;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="r">The reader to read data from.</param>
+ internal DiscoveryEvent(IPortableRawReader r) : base(r)
+ {
+ _eventNode = ReadNode(r);
+ _topologyVersion = r.ReadLong();
+
+ var nodes = IgniteUtils.ReadNodes(r);
+
+ _topologyNodes = nodes == null ? null : new ReadOnlyCollection<IClusterNode>(nodes);
+ }
+
+ /// <summary>
+ /// Gets node that caused this event to be generated. It is potentially different from the node on which this
+ /// event was recorded. For example, node A locally recorded the event that a remote node B joined the topology.
+ /// In this case this method will return ID of B.
+ /// </summary>
+ public IClusterNode EventNode { get { return _eventNode; } }
+
+ /// <summary>
+ /// Gets topology version if this event is raised on topology change and configured discovery
+ /// SPI implementation supports topology versioning.
+ /// </summary>
+ public long TopologyVersion { get { return _topologyVersion; } }
+
+ /// <summary>
+ /// Gets topology nodes from topology snapshot. If SPI implementation does not support versioning, the best
+ /// effort snapshot will be captured.
+ /// </summary>
+ public ICollection<IClusterNode> TopologyNodes { get { return _topologyNodes; } }
+
+ /** <inheritDoc /> */
+ public override string ToShortString()
+ {
+ return string.Format("{0}: EventNode={1}, TopologyVersion={2}, TopologyNodes={3}", Name, EventNode,
+ TopologyVersion, TopologyNodes.Count);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Events/EventBase.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Events/EventBase.cs b/modules/platform/dotnet/Apache.Ignite.Core/Events/EventBase.cs
new file mode 100644
index 0000000..2b905a1
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Events/EventBase.cs
@@ -0,0 +1,160 @@
+/*
+ * 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.Events
+{
+ using System;
+ using Apache.Ignite.Core.Cluster;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Impl.Portable;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Base event implementation.
+ /// </summary>
+ public abstract class EventBase : IEvent, IEquatable<EventBase>
+ {
+ /** */
+ private readonly IgniteGuid _id;
+
+ /** */
+ private readonly long _localOrder;
+
+ /** */
+ private readonly IClusterNode _node;
+
+ /** */
+ private readonly string _message;
+
+ /** */
+ private readonly int _type;
+
+ /** */
+ private readonly string _name;
+
+ /** */
+ private readonly DateTime _timeStamp;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="EventBase"/> class.
+ /// </summary>
+ /// <param name="r">The reader to read data from.</param>
+ protected EventBase(IPortableRawReader r)
+ {
+ _id = IgniteGuid.ReadPortable(r);
+
+ _localOrder = r.ReadLong();
+
+ _node = ReadNode(r);
+
+ _message = r.ReadString();
+ _type = r.ReadInt();
+ _name = r.ReadString();
+ _timeStamp = r.ReadDate() ?? DateTime.Now;
+ }
+
+ /** <inheritDoc /> */
+ public IgniteGuid Id
+ {
+ get { return _id; }
+ }
+
+ /** <inheritDoc /> */
+ public long LocalOrder
+ {
+ get { return _localOrder; }
+ }
+
+ /** <inheritDoc /> */
+ public IClusterNode Node
+ {
+ get { return _node; }
+ }
+
+ /** <inheritDoc /> */
+ public string Message
+ {
+ get { return _message; }
+ }
+
+ /** <inheritDoc /> */
+ public int Type
+ {
+ get { return _type; }
+ }
+
+ /** <inheritDoc /> */
+ public string Name
+ {
+ get { return _name; }
+ }
+
+ /** <inheritDoc /> */
+ public DateTime TimeStamp
+ {
+ get { return _timeStamp; }
+ }
+
+ /** <inheritDoc /> */
+ public virtual string ToShortString()
+ {
+ return ToString();
+ }
+
+ /** <inheritDoc /> */
+ public bool Equals(EventBase other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+
+ return _id.Equals(other._id);
+ }
+
+ /** <inheritDoc /> */
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+
+ return Equals((EventBase) obj);
+ }
+
+ /** <inheritDoc /> */
+ public override int GetHashCode()
+ {
+ return _id.GetHashCode();
+ }
+
+ /** <inheritDoc /> */
+ public override string ToString()
+ {
+ return string.Format("CacheEntry [Name={0}, Type={1}, TimeStamp={2}, Message={3}]", Name, Type, TimeStamp,
+ Message);
+ }
+
+ /// <summary>
+ /// Reads a node from stream.
+ /// </summary>
+ /// <param name="reader">Reader.</param>
+ /// <returns>Node or null.</returns>
+ protected static IClusterNode ReadNode(IPortableRawReader reader)
+ {
+ return ((PortableReaderImpl)reader).Marshaller.Ignite.GetNode(reader.ReadGuid());
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Events/EventReader.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Events/EventReader.cs b/modules/platform/dotnet/Apache.Ignite.Core/Events/EventReader.cs
new file mode 100644
index 0000000..aa9f538
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Events/EventReader.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.Events
+{
+ using System;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Event reader.
+ /// </summary>
+ internal static class EventReader
+ {
+ /// <summary>
+ /// Reads an event.
+ /// </summary>
+ /// <typeparam name="T">Type of the event</typeparam>
+ /// <param name="reader">Reader.</param>
+ /// <returns>Deserialized event.</returns>
+ /// <exception cref="System.InvalidCastException">Incompatible event type.</exception>
+ public static T Read<T>(IPortableReader reader) where T : IEvent
+ {
+ var r = reader.RawReader();
+
+ var clsId = r.ReadInt();
+
+ if (clsId == -1)
+ return default(T);
+
+ return (T) CreateInstance(clsId, r);
+ }
+
+ /// <summary>
+ /// Creates an event instance by type id.
+ /// </summary>
+ /// <param name="clsId">Type id.</param>
+ /// <param name="reader">Reader.</param>
+ /// <returns>Created and deserialized instance.</returns>
+ /// <exception cref="System.InvalidOperationException">Invalid event class id: + clsId</exception>
+ private static IEvent CreateInstance(int clsId, IPortableRawReader reader)
+ {
+ switch (clsId)
+ {
+ case 2: return new CacheEvent(reader);
+ case 3: return new CacheQueryExecutedEvent(reader);
+ case 4: return new CacheQueryReadEvent(reader);
+ case 5: return new CacheRebalancingEvent(reader);
+ case 6: return new CheckpointEvent(reader);
+ case 7: return new DiscoveryEvent(reader);
+ case 8: return new JobEvent(reader);
+ case 9: return new SwapSpaceEvent(reader);
+ case 10: return new TaskEvent(reader);
+ }
+
+ throw new InvalidOperationException("Invalid event class id: " + clsId);
+ }
+ }
+}
\ No newline at end of file