Skip to content

Commit 8ded56a

Browse files
Temp
1 parent 4e6fb23 commit 8ded56a

32 files changed

+30651
-301
lines changed

sample/Sample.Android/NotificationHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Sample.Droid
1515
{
1616
public class NotificationHandler : INotificationHandler
1717
{
18-
public void OnBuildNotification(NotificationCompat.Builder notificationBuilder, NotificationDto notification)
18+
public void OnBuildNotification(NotificationCompat.Builder notificationBuilder, UserNotificationDto notification)
1919
{
2020
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
2121
{

sample/Sample.Android/Resources/Resource.designer.cs

Lines changed: 29809 additions & 79 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// ==========================================================================
2+
// Notifo.io
3+
// ==========================================================================
4+
// Copyright (c) Sebastian Stehle
5+
// All rights reserved. Licensed under the MIT license.
6+
// ==========================================================================
7+
8+
using System;
9+
using System.Collections.Concurrent;
10+
using System.Collections.Generic;
11+
using System.Linq;
12+
using System.Threading.Tasks;
13+
14+
namespace Notifo.SDK.CommandQueue
15+
{
16+
internal sealed class DefaultCommandQueue : ICommandQueue
17+
{
18+
private readonly ICommandStore commandStore;
19+
private readonly ICommandTrigger[] commandTriggers;
20+
private readonly int maxRetries;
21+
private readonly Task task;
22+
private readonly BlockingCollection<QueuedCommand> queue = new BlockingCollection<QueuedCommand>();
23+
private readonly Queue<QueuedCommand> retryQueue = new Queue<QueuedCommand>();
24+
25+
public DefaultCommandQueue(
26+
ICommandStore commandStore,
27+
ICommandTrigger[] commandTriggers,
28+
int maxRetries)
29+
{
30+
this.commandStore = commandStore;
31+
this.commandTriggers = commandTriggers;
32+
this.maxRetries = maxRetries;
33+
34+
foreach (var trigger in commandTriggers)
35+
{
36+
trigger.Start(this);
37+
}
38+
39+
task = Task.Run(RunAsync);
40+
}
41+
42+
public void Dispose()
43+
{
44+
queue.CompleteAdding();
45+
46+
foreach (var trigger in commandTriggers.OfType<IDisposable>())
47+
{
48+
trigger.Dispose();
49+
}
50+
51+
task.Wait();
52+
}
53+
54+
public Task ExecuteAsync(ICommand command)
55+
{
56+
var queudCommand = new QueuedCommand
57+
{
58+
Command = command,
59+
CommandId = Guid.NewGuid()
60+
};
61+
62+
lock (retryQueue)
63+
{
64+
foreach (var existing in retryQueue)
65+
{
66+
if (existing.Command.Merge(command))
67+
{
68+
return Task.CompletedTask;
69+
}
70+
}
71+
72+
retryQueue.Enqueue(queudCommand);
73+
}
74+
75+
Trigger();
76+
77+
return commandStore.StoreAsync(queudCommand).AsTask();
78+
}
79+
80+
public void Trigger()
81+
{
82+
lock (retryQueue)
83+
{
84+
if (retryQueue.TryDequeue(out var dequeued))
85+
{
86+
queue.Add(dequeued);
87+
}
88+
}
89+
}
90+
91+
private async Task RunAsync()
92+
{
93+
var pendingCommands = await commandStore.GetCommandsAsync();
94+
95+
foreach (var command in pendingCommands)
96+
{
97+
retryQueue.Enqueue(command);
98+
}
99+
100+
Trigger();
101+
102+
try
103+
{
104+
foreach (var enqueued in queue.GetConsumingEnumerable())
105+
{
106+
try
107+
{
108+
await enqueued.Command.ExecuteAsync();
109+
110+
// We have completed the command successfully, so we can remove it here.
111+
await commandStore.RemoveAsync(enqueued.CommandId);
112+
113+
// We have just completed a command, so it is very likely that the next one will be successful as well.
114+
Trigger();
115+
}
116+
catch
117+
{
118+
if (enqueued.Retries < maxRetries)
119+
{
120+
enqueued.Retries++;
121+
122+
lock (retryQueue)
123+
{
124+
retryQueue.Enqueue(enqueued);
125+
}
126+
}
127+
}
128+
}
129+
}
130+
catch
131+
{
132+
try
133+
{
134+
queue.CompleteAdding();
135+
}
136+
catch
137+
{
138+
return;
139+
}
140+
}
141+
}
142+
}
143+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// ==========================================================================
2+
// Notifo.io
3+
// ==========================================================================
4+
// Copyright (c) Sebastian Stehle
5+
// All rights reserved. Licensed under the MIT license.
6+
// ==========================================================================
7+
8+
using System.Threading.Tasks;
9+
10+
namespace Notifo.SDK.CommandQueue
11+
{
12+
internal interface ICommand
13+
{
14+
ValueTask ExecuteAsync();
15+
16+
bool Merge(ICommand other);
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// ==========================================================================
2+
// Notifo.io
3+
// ==========================================================================
4+
// Copyright (c) Sebastian Stehle
5+
// All rights reserved. Licensed under the MIT license.
6+
// ==========================================================================
7+
8+
using System.Threading.Tasks;
9+
10+
namespace Notifo.SDK.CommandQueue
11+
{
12+
internal interface ICommandQueue
13+
{
14+
Task ExecuteAsync(ICommand command);
15+
16+
void Trigger();
17+
}
18+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// ==========================================================================
2+
// Notifo.io
3+
// ==========================================================================
4+
// Copyright (c) Sebastian Stehle
5+
// All rights reserved. Licensed under the MIT license.
6+
// ==========================================================================
7+
8+
using System;
9+
using System.Collections.Generic;
10+
using System.Threading.Tasks;
11+
12+
namespace Notifo.SDK.CommandQueue
13+
{
14+
internal interface ICommandStore
15+
{
16+
ValueTask<List<QueuedCommand>> GetCommandsAsync();
17+
18+
ValueTask StoreAsync(QueuedCommand command);
19+
20+
ValueTask RemoveAsync(Guid id);
21+
}
22+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// ==========================================================================
2+
// Notifo.io
3+
// ==========================================================================
4+
// Copyright (c) Sebastian Stehle
5+
// All rights reserved. Licensed under the MIT license.
6+
// ==========================================================================
7+
8+
namespace Notifo.SDK.CommandQueue
9+
{
10+
internal interface ICommandTrigger
11+
{
12+
void Start(ICommandQueue queue);
13+
}
14+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// ==========================================================================
2+
// Notifo.io
3+
// ==========================================================================
4+
// Copyright (c) Sebastian Stehle
5+
// All rights reserved. Licensed under the MIT license.
6+
// ==========================================================================
7+
8+
using System;
9+
10+
namespace Notifo.SDK.CommandQueue
11+
{
12+
internal sealed class QueuedCommand
13+
{
14+
public ICommand Command { get; set; }
15+
16+
public int Retries { get; set; }
17+
18+
public Guid CommandId { get; set; }
19+
}
20+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// ==========================================================================
2+
// Notifo.io
3+
// ==========================================================================
4+
// Copyright (c) Sebastian Stehle
5+
// All rights reserved. Licensed under the MIT license.
6+
// ==========================================================================
7+
8+
using System;
9+
using System.Threading;
10+
11+
namespace Notifo.SDK.CommandQueue
12+
{
13+
internal sealed class TrigerPeriodically : ICommandTrigger, IDisposable
14+
{
15+
private readonly TimeSpan interval;
16+
private Timer? timer;
17+
18+
public TrigerPeriodically(TimeSpan interval)
19+
{
20+
this.interval = interval;
21+
}
22+
23+
public void Dispose()
24+
{
25+
timer?.Dispose();
26+
}
27+
28+
public void Start(ICommandQueue queue)
29+
{
30+
timer ??= new Timer(x =>
31+
{
32+
queue.Trigger();
33+
});
34+
35+
timer.Change((int)interval.TotalMilliseconds, (int)interval.TotalMilliseconds);
36+
}
37+
}
38+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// ==========================================================================
2+
// Notifo.io
3+
// ==========================================================================
4+
// Copyright (c) Sebastian Stehle
5+
// All rights reserved. Licensed under the MIT license.
6+
// ==========================================================================
7+
8+
namespace Notifo.SDK.CommandQueue
9+
{
10+
internal sealed class TriggerOnStart : ICommandTrigger
11+
{
12+
public void Start(ICommandQueue queue)
13+
{
14+
queue.Trigger();
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)