Skip to content

Commit 2df6d74

Browse files
committed
api: proper cleanup of data, improve comments
Signed-off-by: inge4pres <[email protected]>
1 parent f1a77b8 commit 2df6d74

File tree

3 files changed

+43
-21
lines changed

3 files changed

+43
-21
lines changed

src/api/metrics/instrument.zig

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ pub const Instrument = struct {
6868
pub fn counter(self: *Self, comptime T: type) !*Counter(T) {
6969
const c = try self.allocator.create(Counter(T));
7070
c.* = Counter(T).init(self.allocator);
71+
errdefer self.allocator.destroy(c);
7172
self.data = switch (T) {
7273
u16 => .{ .Counter_u16 = c },
7374
u32 => .{ .Counter_u32 = c },
@@ -83,6 +84,7 @@ pub const Instrument = struct {
8384
pub fn upDownCounter(self: *Self, comptime T: type) !*Counter(T) {
8485
const c = try self.allocator.create(Counter(T));
8586
c.* = Counter(T).init(self.allocator);
87+
errdefer self.allocator.destroy(c);
8688
self.data = switch (T) {
8789
i16 => .{ .UpDownCounter_i16 = c },
8890
i32 => .{ .UpDownCounter_i32 = c },
@@ -98,6 +100,7 @@ pub const Instrument = struct {
98100
pub fn histogram(self: *Self, comptime T: type) !*Histogram(T) {
99101
const h = try self.allocator.create(Histogram(T));
100102
h.* = try Histogram(T).init(self.allocator, self.opts.histogramOpts);
103+
errdefer self.allocator.destroy(h);
101104
self.data = switch (T) {
102105
u16 => .{ .Histogram_u16 = h },
103106
u32 => .{ .Histogram_u32 = h },
@@ -115,6 +118,7 @@ pub const Instrument = struct {
115118
pub fn gauge(self: *Self, comptime T: type) !*Gauge(T) {
116119
const g = try self.allocator.create(Gauge(T));
117120
g.* = Gauge(T).init(self.allocator);
121+
errdefer self.allocator.destroy(g);
118122
self.data = switch (T) {
119123
i16 => .{ .Gauge_i16 = g },
120124
i32 => .{ .Gauge_i32 = g },
@@ -410,6 +414,14 @@ pub fn Gauge(comptime T: type) type {
410414

411415
const MeterProvider = @import("meter.zig").MeterProvider;
412416

417+
test "counter with unsupported type does not leak" {
418+
const mp = try MeterProvider.default();
419+
defer mp.shutdown();
420+
const meter = try mp.getMeter(.{ .name = "my-meter" });
421+
const err = meter.createCounter(u1, .{ .name = "a-counter" });
422+
try std.testing.expectError(spec.FormatError.UnsupportedValueType, err);
423+
}
424+
413425
test "meter can create counter instrument and record increase without attributes" {
414426
const mp = try MeterProvider.default();
415427
defer mp.shutdown();
@@ -570,8 +582,10 @@ test "instrument fetches measurements from inner" {
570582
defer std.testing.allocator.free(id);
571583

572584
if (meter.instruments.get(id)) |instrument| {
573-
var measurements = try instrument.getInstrumentsData(std.testing.allocator);
574-
defer measurements.deinit(std.testing.allocator);
585+
const measurements = try instrument.getInstrumentsData(std.testing.allocator);
586+
defer switch (measurements) {
587+
inline else => |list| std.testing.allocator.free(list),
588+
};
575589

576590
std.debug.assert(measurements.int.len == 1);
577591
try std.testing.expectEqual(@as(i64, 100), measurements.int[0].value);

src/api/metrics/measurement.zig

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
const std = @import("std");
2+
const ArrayList = std.ArrayList;
3+
24
const Attribute = @import("../../attributes.zig").Attribute;
35
const Attributes = @import("../../attributes.zig").Attributes;
46
const Kind = @import("instrument.zig").Kind;
@@ -30,17 +32,10 @@ test "datapoint with attributes" {
3032
pub const MeasurementsData = union(enum) {
3133
int: []DataPoint(i64),
3234
double: []DataPoint(f64),
33-
34-
pub fn deinit(self: MeasurementsData, allocator: std.mem.Allocator) void {
35-
switch (self) {
36-
.int => allocator.free(self.int),
37-
.double => allocator.free(self.double),
38-
}
39-
}
4035
};
4136

4237
/// A set of data points with a series of metadata coming from the meter and the instrument.
43-
/// It holds the data collected by a single instrument inside a meter.
38+
/// Holds the data collected by a single instrument inside a meter.
4439
pub const Measurements = struct {
4540
meterName: []const u8,
4641
meterAttributes: ?[]Attribute = null,
@@ -52,6 +47,8 @@ pub const Measurements = struct {
5247
data: MeasurementsData,
5348

5449
pub fn deinit(self: *Measurements, allocator: std.mem.Allocator) void {
55-
self.data.deinit(allocator);
50+
switch (self.data) {
51+
inline else => |list| allocator.free(list),
52+
}
5653
}
5754
};

src/api/metrics/meter.zig

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -428,21 +428,31 @@ const view = @import("../../sdk/metrics/view.zig");
428428
pub const AggregatedMetrics = struct {
429429
fn deduplicate(allocator: std.mem.Allocator, instr: *Instrument, aggregation: view.Aggregation) !MeasurementsData {
430430
// This function is only called on read/export
431-
// which is much less frequent than other SDK operations.
431+
// which is much less frequent than other SDK operations (e.g. counter add).
432432
// TODO: update to @branchHint in 0.14+
433433
@setCold(true);
434434

435435
const allMeasurements: MeasurementsData = try instr.getInstrumentsData(allocator);
436-
defer allMeasurements.deinit(allocator);
436+
defer {
437+
switch (allMeasurements) {
438+
inline else => |list| allocator.free(list),
439+
}
440+
}
437441

438442
switch (allMeasurements) {
439443
.int => {
440444
var deduped = std.ArrayList(DataPoint(i64)).init(allocator);
441-
defer deduped.deinit();
442445

443-
var temp = std.HashMap(Attributes, i64, Attributes.HashContext, std.hash_map.default_max_load_percentage).init(allocator);
446+
var temp = std.HashMap(
447+
Attributes,
448+
i64,
449+
Attributes.HashContext,
450+
std.hash_map.default_max_load_percentage,
451+
).init(allocator);
444452
defer temp.deinit();
445453

454+
// iterate over all measurements and deduplicate them by applying the aggregation function
455+
// using the attributes as the key.
446456
for (allMeasurements.int) |measure| {
447457
switch (aggregation) {
448458
.Drop => return MeasurementsData{ .int = &[_]DataPoint(i64){} },
@@ -465,14 +475,12 @@ pub const AggregatedMetrics = struct {
465475

466476
var iter = temp.iterator();
467477
while (iter.next()) |entry| {
468-
// TODO add sharedAttributes to the measurements attributes.
469478
try deduped.append(DataPoint(i64){ .attributes = entry.key_ptr.*.attributes, .value = entry.value_ptr.* });
470479
}
471480
return .{ .int = try deduped.toOwnedSlice() };
472481
},
473482
.double => {
474483
var deduped = std.ArrayList(DataPoint(f64)).init(allocator);
475-
defer deduped.deinit();
476484

477485
var temp = std.AutoHashMap(Attributes, f64).init(allocator);
478486
defer temp.deinit();
@@ -499,7 +507,6 @@ pub const AggregatedMetrics = struct {
499507

500508
var iter = temp.iterator();
501509
while (iter.next()) |entry| {
502-
// TODO add sharedAttributes (the meter's attributes)to the measurements attributes.
503510
try deduped.append(DataPoint(f64){ .attributes = entry.key_ptr.*.attributes, .value = entry.value_ptr.* });
504511
}
505512
return .{ .double = try deduped.toOwnedSlice() };
@@ -547,7 +554,9 @@ test "aggregated metrics deduplicated from meter without attributes" {
547554
const instr = iter.next() orelse unreachable;
548555

549556
const deduped = try AggregatedMetrics.deduplicate(std.testing.allocator, instr.*, .Sum);
550-
defer deduped.deinit(std.testing.allocator);
557+
defer switch (deduped) {
558+
inline else => |m| std.testing.allocator.free(m),
559+
};
551560

552561
try std.testing.expectEqualDeep(DataPoint(i64){ .value = 4 }, deduped.int[0]);
553562
}
@@ -570,8 +579,10 @@ test "aggregated metrics deduplicated from meter with attributes" {
570579
var iter = meter.instruments.valueIterator();
571580
const instr = iter.next() orelse unreachable;
572581

573-
var deduped = try AggregatedMetrics.deduplicate(std.testing.allocator, instr.*, .Sum);
574-
defer deduped.deinit(std.testing.allocator);
582+
const deduped = try AggregatedMetrics.deduplicate(std.testing.allocator, instr.*, .Sum);
583+
defer switch (deduped) {
584+
inline else => |m| std.testing.allocator.free(m),
585+
};
575586

576587
const attrs = try Attributes.from(std.testing.allocator, .{ "key", val });
577588
defer if (attrs) |a| std.testing.allocator.free(a);

0 commit comments

Comments
 (0)