karlseguin / http.zig

An HTTP/1.1 server for zig
MIT License
454 stars 31 forks source link

Issue's building latest commit using Zon #9

Closed nicholasoxford closed 1 year ago

nicholasoxford commented 1 year ago

Hey! Thanks for all your work.

When getting a simple project set up using http.zig + zon, I ran into an issue with commit 8075e6e414e78fc1728094e39ea1a531b5cb8eb4

I got build errors like: /src/request.zig

error: expected 2 arguments, found 1
const VECTOR_64_NULLS: @Vector(64, u8) = @splat(@as(u8, 255));

To make this easily reproducible, I created a repo. I also think this repo could be a good starting point for people figuring out how to use http.zig + zon

https://github.com/nicholasoxford/http.zon

karlseguin commented 1 year ago

This commit was to accommodate a change to Zig master. Try grabbing the latest version of Zig, or use the f8ae97eb6a5e40a09dd2a7422d9d207073dc7cc3 commit of http.zig.

nicholasoxford commented 1 year ago

Updated master and it built. Thank you 🙏

I have one last question around global context. I've been trying to have a global array of Sessions.

const Global = struct {
    hits: usize = 0,
    l: std.Thread.Mutex = .{},
    sessions: std.ArrayList(Session) = undefined,
};

const Session = struct { sessionId: []const u8, user_id: []const u8, textValue: []const u8 };

const Context = struct {
    global: *Global,
    user_id: ?[]const u8,
};

I've been getting segfault errors when trying to append to the global context. Do I need to be passing around an allocator?

fn createSession(context: Context, req: *httpz.Request, res: *httpz.Response) !void {
    if (try req.json(createSessionRequest)) |body| {
        std.log.info("req body text value is {?s}", .{body.textValue});

        var mutex = context.global.l;
        mutex.lock();
        defer mutex.unlock();

        var newSession = Session{
            .sessionId = "123",
            .user_id = context.user_id.?,
            .textValue = body.textValue,
        };
        // segfaulting here, assuming it has to do with not using a global allocator?
        try context.global.sessions.append(newSession);
    }
...

Link to code with comments:

main/src.zig

karlseguin commented 1 year ago

globla.sessions is undefined.

var global = Global{
  .sessions = std.ArrayList(Session).init(allocator),
};

In general, I think Global and or Context having access to the gpa allocator probably makes sense (Although, in a lot of cases, the req.arena (or res.arena, it's the same thing) will be enough).

If you look at your specific example, sessions is a managed ArrayList (which, in Zig terms, just means it keeps a reference to the allocator so that functions that require an allocator, e.g. append, have access to it. So you need to pass an allocator around, if you need an allocator...in your case, you do need one, but it can be managed internally by the ArrayList.