Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Execution API alignment #88

Merged
merged 40 commits into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
013a9fb
initial
Scooletz May 22, 2023
524e3e8
more
Scooletz May 24, 2023
ce7b0fd
towards blockchain based structure
Scooletz May 24, 2023
51c9650
tests working
Scooletz May 24, 2023
312a35b
storage and state ready!
Scooletz May 24, 2023
1c65f6c
weakly linked blocks
Scooletz May 25, 2023
ece80cb
towards tests
Scooletz May 25, 2023
2f3f0c8
tests
Scooletz May 25, 2023
b4f1edc
block has good memory ownership now
Scooletz May 25, 2023
6967534
cleared situation on multiple blocks per number
Scooletz May 25, 2023
3c0242e
page pool test
Scooletz May 26, 2023
d08c1bd
Blockchain component uses the flusher now, with no data though
Scooletz May 26, 2023
5b6a33a
account as a primitive
Scooletz May 27, 2023
f067a40
simpler page pooling for blocks
Scooletz May 28, 2023
21c4f23
metadata for block in the root
Scooletz May 28, 2023
abd5f5e
Paprika.Runner with blockchain component
Scooletz May 29, 2023
aa7f304
fixed MST extraction
Scooletz May 29, 2023
31e8337
minor comments and tests
Scooletz May 29, 2023
416f0c6
Blockchain blocks mimic the tree of the store now
Scooletz May 29, 2023
8860e56
start application job
Scooletz May 30, 2023
be070fe
fixed blockchain disposal
Scooletz May 30, 2023
224ad89
enumerate all added
Scooletz May 30, 2023
d4f5466
finalization works with a simple test
Scooletz May 30, 2023
d3d4d06
format
Scooletz May 30, 2023
47e97ad
working towards tests
Scooletz May 31, 2023
69f2667
finalized blocks are read now!
Scooletz May 31, 2023
ad19933
refcounting tests added
Scooletz Jun 1, 2023
91b57fa
almost complete
Scooletz Jun 1, 2023
4943d37
more
Scooletz Jun 1, 2023
e7380dd
tests working
Scooletz Jun 2, 2023
6a7f1ab
proper block disposal at the end of the blockchain
Scooletz Jun 5, 2023
07fa934
format and program running
Scooletz Jun 5, 2023
1067067
ref-counting blocks made right
Scooletz Jun 5, 2023
031414a
fixes for tests
Scooletz Jun 6, 2023
60c9217
cleaning up the runner
Scooletz Jun 6, 2023
d3ddb4f
spectre console
Scooletz Jun 6, 2023
dae2d16
much nicer reporting
Scooletz Jun 6, 2023
7740d45
meter adjustements
Scooletz Jun 7, 2023
aa6355e
design flushed
Scooletz Jun 7, 2023
f4c4d2b
one more metric
Scooletz Jun 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 68 additions & 31 deletions docs/design.md

Large diffs are not rendered by default.

98 changes: 98 additions & 0 deletions src/Paprika.Runner/Measurement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System.Diagnostics.Metrics;
using Spectre.Console;
using Spectre.Console.Rendering;

namespace Paprika.Runner;

abstract class Measurement : JustInTimeRenderable
{
private readonly Instrument _instrument;
private const long NoValue = Int64.MaxValue;

private long _value;

private Measurement(Instrument instrument)
{
_instrument = instrument;
}

protected override IRenderable Build()
{
var value = Volatile.Read(ref _value);
return value == NoValue ? new Text("") : new Text(value.ToString());
}

public void Update(double measurement, ReadOnlySpan<KeyValuePair<string, object?>> tags)
{
var updated = Update(measurement);
var previous = Interlocked.Exchange(ref _value, updated);

if (updated != previous)
{
MarkAsDirty();
}
}

protected abstract long Update(double measurement);

public override string ToString() => $"{nameof(Instrument)}: {_instrument.Name}, Value: {Volatile.Read(ref _value)}";

public static Measurement Build(Instrument instrument)
{
var type = instrument.GetType();
if (type.IsGenericType)
{
var definition = type.GetGenericTypeDefinition();

if (definition == typeof(ObservableGauge<>))
{
return new GaugeMeasurement(instrument);
}

if (definition == typeof(Counter<>))
{
return new CounterMeasurement(instrument);
}

if (definition == typeof(Histogram<>))
{
return new HistogramMeasurement(instrument);
}
}

throw new NotImplementedException($"Not implemented for type {type}");
}

private class GaugeMeasurement : Measurement
{
public GaugeMeasurement(Instrument instrument) : base(instrument)
{
}

protected override long Update(double measurement) => (long)measurement;
}

// for now use the last value
private class HistogramMeasurement : Measurement
{
protected override long Update(double measurement)
{
return (long)measurement;
}

public HistogramMeasurement(Instrument instrument) : base(instrument)
{
}
}

private class CounterMeasurement : Measurement
{
private long _sum;

protected override long Update(double measurement) => Interlocked.Add(ref _sum, (long)measurement);

public CounterMeasurement(Instrument instrument) : base(instrument)
{
}
}
}
85 changes: 85 additions & 0 deletions src/Paprika.Runner/MetricsReporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System.Diagnostics.Metrics;
using System.Runtime.InteropServices;
using Spectre.Console;
using Spectre.Console.Rendering;

namespace Paprika.Runner;

public class MetricsReporter : IDisposable
{
private readonly object _sync = new();
private readonly MeterListener _listener;
private readonly Dictionary<Meter, Dictionary<Instrument, Measurement>> _instrument2State = new();

public IRenderable Renderer { get; }

public MetricsReporter()
{
var table = new Table();

Renderer = table;

table.AddColumn(new TableColumn("Meter").LeftAligned());
table.AddColumn(new TableColumn("Instrument").LeftAligned());
table.AddColumn(new TableColumn("Value").Width(10).RightAligned());
table.AddColumn(new TableColumn("Unit").RightAligned());

_listener = new MeterListener
{
InstrumentPublished = (instrument, listener) =>
{
lock (_sync)
{
var meter = instrument.Meter;
ref var dict = ref CollectionsMarshal.GetValueRefOrAddDefault(_instrument2State, meter,
out var exists);

if (!exists)
{
dict = new Dictionary<Instrument, Measurement>();
}

var state = Measurement.Build(instrument);
dict!.Add(instrument, state);

table.AddRow(new Text(meter.Name.Replace("Paprika.", "")),
new Text(instrument.Name),
state,
new Text(instrument.Unit!));

listener.EnableMeasurementEvents(instrument, state);
}
},
MeasurementsCompleted = (instrument, cookie) =>
{
lock (_sync)
{
var instruments = _instrument2State[instrument.Meter];
instruments.Remove(instrument, out _);
if (instruments.Count == 0)
_instrument2State.Remove(instrument.Meter);
}
}
};

_listener.Start();

_listener.SetMeasurementEventCallback<double>((i, m, l, c) => ((Measurement)c!).Update(m, l));
_listener.SetMeasurementEventCallback<float>((i, m, l, c) => ((Measurement)c!).Update(m, l));
_listener.SetMeasurementEventCallback<long>((i, m, l, c) => ((Measurement)c!).Update(m, l));
_listener.SetMeasurementEventCallback<int>((i, m, l, c) => ((Measurement)c!).Update(m, l));
_listener.SetMeasurementEventCallback<short>((i, m, l, c) => ((Measurement)c!).Update(m, l));
_listener.SetMeasurementEventCallback<byte>((i, m, l, c) => ((Measurement)c!).Update(m, l));
_listener.SetMeasurementEventCallback<decimal>((i, m, l, c) => ((Measurement)c!).Update((double)m, l));
}

public void Observe()
{
_listener.RecordObservableInstruments();
}

public void Dispose()
{
_listener.Dispose();
}
}
1 change: 1 addition & 0 deletions src/Paprika.Runner/Paprika.Runner.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

<ItemGroup>
<PackageReference Include="HdrHistogram" Version="2.5.0" />
<PackageReference Include="Spectre.Console" Version="0.47.1-preview.0.6" />
</ItemGroup>

</Project>
Loading