/
MsgCommandHandlerActor.cs
121 lines (105 loc) · 4.98 KB
/
MsgCommandHandlerActor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Configuration;
using Petabridge.Cmd.Host;
namespace Petabridge.Cmd.QuickStart
{
/// <summary>
/// Actor responsible for handling all <see cref="Command"/>s defined inside <see cref="MsgCommands.Palette"/>
/// </summary>
public class MsgCommandHandlerActor : CommandHandlerActor
{
private readonly IActorRef _messageMemorizer;
private static readonly Regex TimeRegex = new Regex(@"^(?<value>([0-9]+(\.[0-9]+)?))\s*(?<unit>(ms|s|h|m|d))$", RegexOptions.Compiled);
public MsgCommandHandlerActor(IActorRef messageMemorizer) : base(MsgCommands.Palette)
{
_messageMemorizer = messageMemorizer;
Receive<Command>(c => c.Name.Equals(MsgCommands.CheckMessages.Name), command => ExecuteCommand(command, HandleFetch));
Receive<Command>(c => c.Name.Equals(MsgCommands.Write.Name), command => ExecuteCommand(command, HandleWrite));
Receive<Command>(c => c.Name.Equals(MsgCommands.Echo.Name), command => ExecuteCommand(command, HandleEcho));
Receive<Command>(c => c.Name.Equals(MsgCommands.Purge.Name), command => ExecuteCommand(command, HandlePurge));
}
public void HandlePurge(Command purge)
{
_messageMemorizer.Tell(MessageMemorizerActor.PurgeMessages.Instance, Sender);
}
public void HandleWrite(Command write)
{
var msg =
write.Arguments.SingleOrDefault(
x => MsgCommands.Write.ArgumentsByName["message"].Switch.Contains(x.Item1))?
.Item2;
_messageMemorizer.Tell(new MessageMemorizerActor.Message(msg, DateTime.UtcNow, Sender.Path.Name), Sender);
}
public void HandleEcho(Command echo)
{
var msg =
echo.Arguments.SingleOrDefault(
x => MsgCommands.Echo.ArgumentsByName["message"].Switch.Contains(x.Item1))?
.Item2;
Sender.Tell(new CommandResponse(new MessageMemorizerActor.Message(msg, DateTime.UtcNow, Sender.Path.Name).ToString())); // will echo what was written on commandline
}
public void HandleFetch(Command fetch)
{
// check if we have a timeframe for the message specified
// what this code does: scans the set of arguments in `fetch` to see
// if any of the switches for the `since` argument have been used, and if
// so return the value for that argument. Otherwise, return null.
var containsTimeframe =
fetch.Arguments.SingleOrDefault(
x => MsgCommands.CheckMessages.ArgumentsByName["since"].Switch.Contains(x.Item1))?.Item2;
if (containsTimeframe == null)
{
_messageMemorizer.Tell(new MessageMemorizerActor.FetchMessages(), Sender); // preserve sender so client gets replies directly
return;
}
// using regular expression to extract the time format
var m = TimeRegex.Match(containsTimeframe);
if (!m.Success)
{
Sender.Tell(new ErroredCommandResponse($"Unable to extract time format from {containsTimeframe}. Should be in format of [value][ms|s|m|h|d] for milliseconds, seconds, minutes, hours, or days respectively."));
return;
}
try
{
var unit = m.Groups["unit"].Value;
var value = Int32.Parse(m.Groups["value"].Value);
if (value < 0)
{
Sender.Tell(new ErroredCommandResponse($"Need to pass in positive time value for `since` argument. Instead, received [{value} {unit}]"));
return;
}
TimeSpan time = TimeSpan.Zero;
switch (unit)
{
case "ms":
time = TimeSpan.FromMilliseconds(value);
break;
case "s":
time = TimeSpan.FromSeconds(value);
break;
case "m":
time = TimeSpan.FromMinutes(value);
break;
case "h":
time = TimeSpan.FromHours(value);
break;
case "d":
time = TimeSpan.FromDays(value);
break;
}
// make sure the original sender is passed along so reply goes to client
_messageMemorizer.Tell(new MessageMemorizerActor.FetchMessages(time), Sender);
}
catch (Exception ex)
{
Sender.Tell(new ErroredCommandResponse($"Error occurred while processing command: {ex.Message}"));
}
}
}
}