Skip to content

Commit 99e2ebf

Browse files
committed
store iid in application data directory
1 parent b9f6975 commit 99e2ebf

File tree

2 files changed

+49
-18
lines changed

2 files changed

+49
-18
lines changed

src/app.zig

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const Loop = @import("jsruntime").Loop;
44
const Allocator = std.mem.Allocator;
55
const Telemetry = @import("telemetry/telemetry.zig").Telemetry;
66

7+
const log = std.log.scoped(.app);
8+
79
pub const RunMode = enum {
810
serve,
911
fetch,
@@ -13,6 +15,7 @@ pub const RunMode = enum {
1315
// might need.
1416
pub const App = struct {
1517
loop: *Loop,
18+
app_dir_path: ?[]const u8,
1619
allocator: Allocator,
1720
telemetry: Telemetry,
1821

@@ -23,19 +26,42 @@ pub const App = struct {
2326
loop.* = try Loop.init(allocator);
2427
errdefer loop.deinit();
2528

26-
const telemetry = Telemetry.init(allocator, run_mode);
29+
const app_dir_path = getAndMakeAppDir(allocator);
30+
const telemetry = Telemetry.init(allocator, run_mode, app_dir_path);
2731
errdefer telemetry.deinit();
2832

2933
return .{
3034
.loop = loop,
3135
.allocator = allocator,
3236
.telemetry = telemetry,
37+
.app_dir_path = app_dir_path,
3338
};
3439
}
3540

3641
pub fn deinit(self: *App) void {
42+
if (self.app_dir_path) |app_dir_path| {
43+
self.allocator.free(app_dir_path);
44+
}
45+
3746
self.telemetry.deinit();
3847
self.loop.deinit();
3948
self.allocator.destroy(self.loop);
4049
}
4150
};
51+
52+
fn getAndMakeAppDir(allocator: Allocator) ?[]const u8 {
53+
const app_dir_path = std.fs.getAppDataDir(allocator, "lightpanda") catch |err| {
54+
log.warn("failed to get lightpanda data dir: {}", .{err});
55+
return null;
56+
};
57+
58+
std.fs.makeDirAbsolute(app_dir_path) catch |err| switch (err) {
59+
error.PathAlreadyExists => return app_dir_path,
60+
else => {
61+
allocator.free(app_dir_path);
62+
log.warn("failed to create lightpanda data dir: {}", .{err});
63+
return null;
64+
}
65+
};
66+
return app_dir_path;
67+
}

src/telemetry/telemetry.zig

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const uuidv4 = @import("../id.zig").uuidv4;
88
const RunMode = @import("../app.zig").RunMode;
99

1010
const log = std.log.scoped(.telemetry);
11-
const ID_FILE = "lightpanda.id";
11+
const IID_FILE = "iid";
1212

1313
pub const Telemetry = TelemetryT(blk: {
1414
if (builtin.mode == .Debug or builtin.is_test) break :blk NoopProvider;
@@ -29,7 +29,7 @@ fn TelemetryT(comptime P: type) type {
2929

3030
const Self = @This();
3131

32-
pub fn init(allocator: Allocator, run_mode: RunMode) Self {
32+
pub fn init(allocator: Allocator, run_mode: RunMode, app_dir_path: ?[]const u8) Self {
3333
const disabled = std.process.hasEnvVarConstant("LIGHTPANDA_DISABLE_TELEMETRY");
3434
if (builtin.mode != .Debug and builtin.is_test == false) {
3535
log.info("telemetry {s}", .{if (disabled) "disabled" else "enabled"});
@@ -39,7 +39,7 @@ fn TelemetryT(comptime P: type) type {
3939
.disabled = disabled,
4040
.run_mode = run_mode,
4141
.provider = try P.init(allocator),
42-
.iid = if (disabled) null else getOrCreateId(),
42+
.iid = if (disabled) null else getOrCreateId(app_dir_path),
4343
};
4444
}
4545

@@ -59,9 +59,17 @@ fn TelemetryT(comptime P: type) type {
5959
};
6060
}
6161

62-
fn getOrCreateId() ?[36]u8 {
62+
fn getOrCreateId(app_dir_path_: ?[]const u8) ?[36]u8 {
63+
const app_dir_path = app_dir_path_ orelse return null;
64+
6365
var buf: [37]u8 = undefined;
64-
const data = std.fs.cwd().readFile(ID_FILE, &buf) catch |err| switch (err) {
66+
var dir = std.fs.openDirAbsolute(app_dir_path, .{}) catch |err| {
67+
log.warn("failed to open data directory '{s}': {}", .{ app_dir_path, err });
68+
return null;
69+
};
70+
defer dir.close();
71+
72+
const data = dir.readFile(IID_FILE, &buf) catch |err| switch (err) {
6573
error.FileNotFound => &.{},
6674
else => {
6775
log.warn("failed to open id file: {}", .{err});
@@ -76,7 +84,7 @@ fn getOrCreateId() ?[36]u8 {
7684
}
7785

7886
uuidv4(&id);
79-
std.fs.cwd().writeFile(.{ .sub_path = ID_FILE, .data = &id }) catch |err| {
87+
dir.writeFile(.{ .sub_path = IID_FILE, .data = &id }) catch |err| {
8088
log.warn("failed to write to id file: {}", .{err});
8189
return null;
8290
};
@@ -115,30 +123,27 @@ test "telemetry: disabled by environment" {
115123
}
116124
};
117125

118-
var telemetry = TelemetryT(FailingProvider).init(testing.allocator, .serve);
126+
var telemetry = TelemetryT(FailingProvider).init(testing.allocator, .serve, null);
119127
defer telemetry.deinit();
120128
telemetry.record(.{ .run = {} });
121129
}
122130

123131
test "telemetry: getOrCreateId" {
124-
defer std.fs.cwd().deleteFile(ID_FILE) catch {};
132+
defer std.fs.cwd().deleteFile("/tmp/" ++ IID_FILE) catch {};
125133

126-
std.fs.cwd().deleteFile(ID_FILE) catch {};
134+
std.fs.cwd().deleteFile("/tmp/" ++ IID_FILE) catch {};
127135

128-
const id1 = getOrCreateId().?;
129-
const id2 = getOrCreateId().?;
136+
const id1 = getOrCreateId("/tmp/").?;
137+
const id2 = getOrCreateId("/tmp/").?;
130138
try testing.expectEqualStrings(&id1, &id2);
131139

132-
std.fs.cwd().deleteFile(ID_FILE) catch {};
133-
const id3 = getOrCreateId().?;
140+
std.fs.cwd().deleteFile("/tmp/" ++ IID_FILE) catch {};
141+
const id3 = getOrCreateId("/tmp/").?;
134142
try testing.expectEqual(false, std.mem.eql(u8, &id1, &id3));
135143
}
136144

137145
test "telemetry: sends event to provider" {
138-
defer std.fs.cwd().deleteFile(ID_FILE) catch {};
139-
std.fs.cwd().deleteFile(ID_FILE) catch {};
140-
141-
var telemetry = TelemetryT(MockProvider).init(testing.allocator, .serve);
146+
var telemetry = TelemetryT(MockProvider).init(testing.allocator, .serve, "/tmp/");
142147
defer telemetry.deinit();
143148
const mock = &telemetry.provider;
144149

0 commit comments

Comments
 (0)