-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathProgram.cs
More file actions
175 lines (145 loc) · 6.17 KB
/
Program.cs
File metadata and controls
175 lines (145 loc) · 6.17 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using ExampleProject.Events;
using Lokad.AzureEventStore;
using Lokad.AzureEventStore.Cache;
namespace ExampleProject;
public sealed class Program
{
public const string AccountName = "";
public const string AccountKey = "";
public static readonly string LocalCache =
RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
? "/var/Lokad/example-cache"
: @"C:\LokadData\example-cache";
public const string ConnectionString = @"DefaultEndpointsProtocol=https;AccountName=" + AccountName + ";AccountKey=" + AccountKey + ";Container=example";
static async Task Main(string[] args)
{
var config = new StorageConfiguration(ConnectionString);
// The stream service owns a background process that we need
// to be able to kill.
var cts = new CancellationTokenSource();
var svc = EventStreamService<IEvent, State>.StartNew(
// This is where the events are stored
storage: config,
// These are the projections used to turn the event stream
// into an up-to-date state (our example only has one projection)
projections: [new Projection()],
// This is where we would write the projection snapshots, if
// we had implemented them.
projectionCache: new MappedCacheProvider(LocalCache),
// This is where we would write a memory-mapped state, if we
// had implemented them.
projectionFolder: null,
// This is used by the service to emit messages about what is happening
log: new Log(),
// This cancellation token stops the background process.
cancel: cts.Token);
svc.RefreshPeriod = 10 * 60;
// Once the stream is fully loaded, save it to cache.
_ = svc.Ready.ContinueWith(_ => svc.TrySaveAsync(cts.Token));
while (true)
{
if (svc.IsReady)
Console.WriteLine("{0} words in index", svc.LocalState.Index.Count);
var line = Console.ReadLine();
if (line == null || line == "QUIT") break;
if (!svc.IsReady)
{
// The service starts catching up with the stream. This may
// take a short while if the stream becomes very long.
Console.WriteLine("Service not ready, please wait.");
continue;
}
if (line.StartsWith("file "))
{
var path = line.Substring("file ".Length);
string text;
try
{
text = File.ReadAllText(path);
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
continue;
}
if (text.Length > 65536)
text = text.Substring(0, 65536);
var id =
await svc.TransactionAsync(transaction =>
{
var count = transaction.State.Documents.Count;
transaction.Add(new DocumentAdded(count, path, text));
return count;
}, CancellationToken.None);
Console.WriteLine("Added as document {0}", id.More);
continue;
}
if (line.StartsWith("folder "))
{
var dir = line.Substring("folder ".Length);
foreach (var path in Directory.GetFiles(dir))
{
var text = File.ReadAllText(path);
if (text.Length > 65536)
text = text.Substring(0, 65536);
var id =
await svc.TransactionAsync(transaction =>
{
var count = transaction.State.Documents.Count;
transaction.Add(new DocumentAdded(count, path, text));
return count;
}, CancellationToken.None);
Console.WriteLine("Added document {0} = {1}", id.More, path);
}
continue;
}
if (line.StartsWith("find "))
{
var word = line.Substring("find ".Length).ToLower();
var state = await svc.CurrentState(CancellationToken.None);
if (!state.Index.TryGetValue(word, out var list))
{
Console.WriteLine("Word '{0}' appears in 0 documents", word);
continue;
}
var docs = state.DocumentLists[list];
Console.WriteLine("Word '{0}' appears in {1} documents", word, docs.Count);
foreach (var doc in docs)
Console.WriteLine(" {0}: {1}", doc, state.Documents[doc].Path);
continue;
}
}
cts.Cancel();
}
/// <summary>
/// Implements <see cref="ILogAdapter"/> to display logging information to
/// the console, for illustration purposes.
/// </summary>
private sealed class Log : ILogAdapter
{
public void Debug(string message) => Write(ConsoleColor.Gray, message);
public void Info(string message) => Write(ConsoleColor.White, message);
public void Warning(string message, Exception ex = null) => Write(ConsoleColor.Yellow, message, ex);
public void Error(string message, Exception ex = null) => Write(ConsoleColor.Red, message, ex);
private void Write(ConsoleColor color, string message, Exception exception = null)
{
var c = Console.ForegroundColor;
Console.ForegroundColor = color;
try
{
Console.WriteLine("[ES] {0}", message);
if (exception != null)
Console.WriteLine(" {0}: {1}", exception.GetType(), exception.Message);
}
finally
{
Console.ForegroundColor = c;
}
}
}
}