[
https://issues.apache.org/jira/browse/IGNITE-22349?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Alexey Kukushkin updated IGNITE-22349:
--------------------------------------
Description:
We want Apache Ignite to support [priority
ordering|https://ignite.apache.org/docs/latest/distributed-computing/job-scheduling#priority-ordering]
of Ignite.NET compute jobs on the same node.
h4. Analysis
{{PriorityQueueCollisionSpi}} does priority ordering. The problem is the
{{PriorityQueueCollisionSpi}} expects the user to provide job priorities
via the {{ComputeTaskSession}}'s "{{grid.task.priority}}" attribute and the
{{ComputeTaskSession}} is not available in Ignite.NET.
It looks like the requirement is to add an injectable {{ComputeTaskSession}} in
Ignite.NET exposing the {{SetAttributes}} operation similar to what the
{{ComputeTaskSession}} does in Java.
h4. Reproducer
We expect more or less ordered output from the below reproducer. The output may
not be completely ordered since this reproducer does not guarantee :
{noformat}
>>> Completed job with priority 0
>>> Completed job with priority 9
>>> Completed job with priority 8
>>> Completed job with priority 7
>>> Completed job with priority 6
>>> Completed job with priority 5
>>> Completed job with priority 4
>>> Completed job with priority 3
>>> Completed job with priority 2
>>> Completed job with priority 1
{noformat}
{{PriorityQueueCollisionSpiTest.cs}}:
{code:java}
public class PriorityQueueCollisionSpiTest
{
private static ITestOutputHelper? _output;
/// <summary>
/// Schedules jobs according to <see
cref="IComputeTask{TArg,TJobRes,TRes}"/>'s priority.
/// </summary>
[Fact]
public void SchedulesJobsAccordingToTaskPriority()
{
// Given an Ignite cluster consisting of server and client nodes
using var ignored = Ignition.Start(GetIgniteConfiguration("server1"));
var igniteConfiguration = GetIgniteConfiguration("app1");
igniteConfiguration.ClientMode = true;
using var ignite = Ignition.Start(igniteConfiguration);
var igniteCompute = ignite.GetCompute();
// And the user asynchronously executes multiple tasks, each task
starting a job having increasing priority
const int jobCount = 10;
ICollection<Task> futureResultCollection = new List<Task>(jobCount);
for (var priority = 0; priority < jobCount; priority++)
{
var task = new PriorityTask(priority);
var futureResult = igniteCompute.ExecuteAsync(task, jobCount);
futureResultCollection.Add(futureResult);
}
// When all the jobs complete
Task.WaitAll(futureResultCollection.ToArray());
// Then the ">>> Completed job with priority" console output
demonstrates that the jobs completed in the
// decreasing priority order, more or less.
}
private static IgniteConfiguration GetIgniteConfiguration(string
igniteName) =>
new()
{
ConsistentId = igniteName,
IgniteInstanceName = igniteName,
SpringConfigUrl = "ignite-sandbox.xml",
DiscoverySpi = new TcpDiscoverySpi
{
IpFinder = new TcpDiscoveryStaticIpFinder {Endpoints = new
List<string> {"127.0.0.1:48700"}},
LocalPort = 48700
},
FailureDetectionTimeout = TimeSpan.FromMinutes(10),
ClientFailureDetectionTimeout = TimeSpan.FromMinutes(10),
JvmOptions = new List<string>
{"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"}
};
/// <summary>
/// <see cref="IComputeTask{TArg,TJobRes,TRes}"/> implementation that
single <see cref="IComputeJob{TRes}"/>s with
/// the specified priority.
/// </summary>
[ComputeTaskSessionFullSupport]
private sealed class PriorityTask : ComputeTaskSplitAdapter<int, bool, bool>
{
private readonly int _priority;
[TaskSessionResource] private IComputeTaskSession _taskSession;
[InstanceResource] private IIgnite _ignite;
public PriorityTask(int priority)
{
_priority = priority;
}
/// <inheritdoc />
public override bool Reduce(IList<IComputeJobResult<bool>> results) =>
results.All(r => r.Data);
/// <inheritdoc />
protected override ICollection<IComputeJob<bool>> Split(int gridSize,
int jobCount)
{
IComputeJob<bool> job = new PriorityJob(_priority);
_taskSession.SetAttribute("grid.task.priority", _priority);
var actual = _taskSession.GetAttribute<int>("grid.task.priority");
Assert.Equal(_priority, actual);
return new List<IComputeJob<bool>> {job};
}
}
/// <summary>
/// <see cref="IComputeJob{TRes}"/> implementation with a priority
indicator.
/// </summary>
private class PriorityJob : ComputeJobAdapter<bool>
{
private readonly int _priority;
[TaskSessionResource] private IComputeTaskSession _taskSession;
[InstanceResource] private IIgnite _ignite;
public PriorityJob(int priority)
{
_priority = priority;
}
/// <inheritdoc />
public override bool Execute()
{
_output?.WriteLine($">>> Completed job with priority {_priority}");
return true;
}
}
}
{code}
{{ignite-sandbox.xml}}:
{code:xml}
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd"
>
<bean class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="collisionSpi">
<bean
class="org.apache.ignite.spi.collision.priorityqueue.PriorityQueueCollisionSpi">
<property name="parallelJobsNumber" value="1"/>
<property name="starvationPreventionEnabled" value="false"/>
</bean>
</property>
</bean>
</beans>
{code}
was:
We want Apache Ignite to support [priority
ordering|https://ignite.apache.org/docs/latest/distributed-computing/job-scheduling#priority-ordering]
of Ignite.NET compute jobs on the same node.
h3. Analysis
{{PriorityQueueCollisionSpi}} does priority ordering. The problem is the
{{PriorityQueueCollisionSpi}} expects the user to provide job priorities
via the {{ComputeTaskSession}}'s "{{grid.task.priority}}" attribute and the
{{ComputeTaskSession}} is not available in Ignite.NET.
It looks like the requirement is to add an injectable {{ComputeTaskSession}} in
Ignite.NET exposing the {{SetAttributes}} operation similar to what the
{{ComputeTaskSession}} does in Java.
> Ignite.NET support for priority ordering of Compute jobs
> --------------------------------------------------------
>
> Key: IGNITE-22349
> URL: https://issues.apache.org/jira/browse/IGNITE-22349
> Project: Ignite
> Issue Type: Improvement
> Components: .NET, compute, platforms
> Affects Versions: 2.16
> Reporter: Alexey Kukushkin
> Assignee: Alexey Kukushkin
> Priority: Major
> Labels: .net, compute, platforms
>
> We want Apache Ignite to support [priority
> ordering|https://ignite.apache.org/docs/latest/distributed-computing/job-scheduling#priority-ordering]
> of Ignite.NET compute jobs on the same node.
> h4. Analysis
> {{PriorityQueueCollisionSpi}} does priority ordering. The problem is the
> {{PriorityQueueCollisionSpi}} expects the user to provide job priorities
> via the {{ComputeTaskSession}}'s "{{grid.task.priority}}" attribute and the
> {{ComputeTaskSession}} is not available in Ignite.NET.
> It looks like the requirement is to add an injectable {{ComputeTaskSession}}
> in Ignite.NET exposing the {{SetAttributes}} operation similar to what the
> {{ComputeTaskSession}} does in Java.
> h4. Reproducer
> We expect more or less ordered output from the below reproducer. The output
> may not be completely ordered since this reproducer does not guarantee :
> {noformat}
> >>> Completed job with priority 0
> >>> Completed job with priority 9
> >>> Completed job with priority 8
> >>> Completed job with priority 7
> >>> Completed job with priority 6
> >>> Completed job with priority 5
> >>> Completed job with priority 4
> >>> Completed job with priority 3
> >>> Completed job with priority 2
> >>> Completed job with priority 1
> {noformat}
> {{PriorityQueueCollisionSpiTest.cs}}:
> {code:java}
> public class PriorityQueueCollisionSpiTest
> {
> private static ITestOutputHelper? _output;
> /// <summary>
> /// Schedules jobs according to <see
> cref="IComputeTask{TArg,TJobRes,TRes}"/>'s priority.
> /// </summary>
> [Fact]
> public void SchedulesJobsAccordingToTaskPriority()
> {
> // Given an Ignite cluster consisting of server and client nodes
> using var ignored = Ignition.Start(GetIgniteConfiguration("server1"));
> var igniteConfiguration = GetIgniteConfiguration("app1");
> igniteConfiguration.ClientMode = true;
> using var ignite = Ignition.Start(igniteConfiguration);
> var igniteCompute = ignite.GetCompute();
>
> // And the user asynchronously executes multiple tasks, each task
> starting a job having increasing priority
> const int jobCount = 10;
> ICollection<Task> futureResultCollection = new List<Task>(jobCount);
> for (var priority = 0; priority < jobCount; priority++)
> {
> var task = new PriorityTask(priority);
> var futureResult = igniteCompute.ExecuteAsync(task, jobCount);
> futureResultCollection.Add(futureResult);
> }
> // When all the jobs complete
> Task.WaitAll(futureResultCollection.ToArray());
>
> // Then the ">>> Completed job with priority" console output
> demonstrates that the jobs completed in the
> // decreasing priority order, more or less.
> }
> private static IgniteConfiguration GetIgniteConfiguration(string
> igniteName) =>
> new()
> {
> ConsistentId = igniteName,
> IgniteInstanceName = igniteName,
> SpringConfigUrl = "ignite-sandbox.xml",
> DiscoverySpi = new TcpDiscoverySpi
> {
> IpFinder = new TcpDiscoveryStaticIpFinder {Endpoints = new
> List<string> {"127.0.0.1:48700"}},
> LocalPort = 48700
> },
> FailureDetectionTimeout = TimeSpan.FromMinutes(10),
> ClientFailureDetectionTimeout = TimeSpan.FromMinutes(10),
> JvmOptions = new List<string>
> {"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"}
> };
> /// <summary>
> /// <see cref="IComputeTask{TArg,TJobRes,TRes}"/> implementation that
> single <see cref="IComputeJob{TRes}"/>s with
> /// the specified priority.
> /// </summary>
> [ComputeTaskSessionFullSupport]
> private sealed class PriorityTask : ComputeTaskSplitAdapter<int, bool,
> bool>
> {
> private readonly int _priority;
> [TaskSessionResource] private IComputeTaskSession _taskSession;
> [InstanceResource] private IIgnite _ignite;
> public PriorityTask(int priority)
> {
> _priority = priority;
> }
> /// <inheritdoc />
> public override bool Reduce(IList<IComputeJobResult<bool>> results)
> => results.All(r => r.Data);
> /// <inheritdoc />
> protected override ICollection<IComputeJob<bool>> Split(int gridSize,
> int jobCount)
> {
> IComputeJob<bool> job = new PriorityJob(_priority);
> _taskSession.SetAttribute("grid.task.priority", _priority);
> var actual = _taskSession.GetAttribute<int>("grid.task.priority");
> Assert.Equal(_priority, actual);
> return new List<IComputeJob<bool>> {job};
> }
> }
> /// <summary>
> /// <see cref="IComputeJob{TRes}"/> implementation with a priority
> indicator.
> /// </summary>
> private class PriorityJob : ComputeJobAdapter<bool>
> {
> private readonly int _priority;
> [TaskSessionResource] private IComputeTaskSession _taskSession;
> [InstanceResource] private IIgnite _ignite;
> public PriorityJob(int priority)
> {
> _priority = priority;
> }
> /// <inheritdoc />
> public override bool Execute()
> {
> _output?.WriteLine($">>> Completed job with priority
> {_priority}");
> return true;
> }
> }
> }
> {code}
> {{ignite-sandbox.xml}}:
> {code:xml}
> <?xml version="1.0" encoding="utf-8"?>
> <beans xmlns="http://www.springframework.org/schema/beans"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:util="http://www.springframework.org/schema/util"
> xmlns:context="http://www.springframework.org/schema/context"
> xsi:schemaLocation="
> http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans.xsd
> http://www.springframework.org/schema/util
> http://www.springframework.org/schema/util/spring-util-2.5.xsd"
> >
> <bean class="org.apache.ignite.configuration.IgniteConfiguration">
> <property name="collisionSpi">
> <bean
> class="org.apache.ignite.spi.collision.priorityqueue.PriorityQueueCollisionSpi">
> <property name="parallelJobsNumber" value="1"/>
> <property name="starvationPreventionEnabled" value="false"/>
> </bean>
> </property>
> </bean>
> </beans>
> {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)