mirror of
https://github.com/zigzap/zap.git
synced 2025-10-21 07:34:08 +00:00
updated READE, CONTRIBUTING
This commit is contained in:
parent
307543c5a0
commit
0f135a2ff4
3 changed files with 264 additions and 2 deletions
36
CONTRIBUTING.md
Normal file
36
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Contributing to ZAP
|
||||||
|
|
||||||
|
## The git pre-commit hook
|
||||||
|
|
||||||
|
**NOTE**: The discussed pre-commit hook doesn't exist yet. I plan to introduce
|
||||||
|
it soon. At least the (mental) note is typed into existence now.
|
||||||
|
|
||||||
|
git hook for add / commit, checking for src/deps/facilio in the file list that
|
||||||
|
only lets you go through with the operation if a specific env var is set
|
||||||
|
|
||||||
|
why is that? we don't use a fork of facilio. we use their repo as submodule. on
|
||||||
|
build, we apply a patch to the submodule. after applying, the submodule is
|
||||||
|
dirty. it refers to a new head only present on the current machine. if we were
|
||||||
|
to commit the submodule now and push those changes, future git submodule update
|
||||||
|
--init calls will fail on fresh clones of the repo. We want to avoid this
|
||||||
|
mistake that easily happens if you use a `git add . && git commit` workflow. On
|
||||||
|
the other hand, if upstream facilio changes, we still want to be able to upgrade
|
||||||
|
to it by pulling the changes and recording the new head via git commit to our
|
||||||
|
own repo. Hence, just ignoring the submodule via `.gitignore` is not an option.
|
||||||
|
That's why we introduced the hook (// that gets installed on build.)
|
||||||
|
|
||||||
|
## Communicating
|
||||||
|
|
||||||
|
I strongly favor [SourceHut](https://sr.ht)'s workflows, so I'll probably set up
|
||||||
|
a mailing list for discussions and patches. You can reach me
|
||||||
|
[there](https://sr.ht/~renerocksai) via
|
||||||
|
[e-mail](~renerocksai/public-inbox@lists.sr.ht).
|
||||||
|
|
||||||
|
A whole discord server as another option, while a funny idea, seems like a bit
|
||||||
|
of an overkill. You can reach me on [the zig showtime discord
|
||||||
|
server](https://discord.gg/CBzE3VMb) under the handle renerocksai
|
||||||
|
(renerocksai#1894).
|
||||||
|
|
||||||
|
Pull-requests and issues are, of course, welcome, too - and may be, for the time
|
||||||
|
being, the most both sane and GitHub-friendly way of communicating.
|
||||||
|
|
36
README.md
36
README.md
|
@ -14,6 +14,9 @@ framework](https://facil.io).
|
||||||
|
|
||||||
**⚡ZAP⚡ IS SUPER ALPHA**
|
**⚡ZAP⚡ IS SUPER ALPHA**
|
||||||
|
|
||||||
|
_Under the hood, everything is super robust and fast. My zig wrappers are fresh,
|
||||||
|
juicy, and alpha._
|
||||||
|
|
||||||
Here's what works:
|
Here's what works:
|
||||||
|
|
||||||
- **Super easy build process**: zap's `build.zig` fetches git sub-modules,
|
- **Super easy build process**: zap's `build.zig` fetches git sub-modules,
|
||||||
|
@ -42,7 +45,7 @@ projects, serving thousands of concurrent clients.
|
||||||
Claiming to be blazingly fast is the new black. At least, zap doesn't slow you
|
Claiming to be blazingly fast is the new black. At least, zap doesn't slow you
|
||||||
down and if your server performs poorly, it's probably not exactly zap's fault.
|
down and if your server performs poorly, it's probably not exactly zap's fault.
|
||||||
Zap relies on the [facil.io](https://facil.io) framework and so it can't really
|
Zap relies on the [facil.io](https://facil.io) framework and so it can't really
|
||||||
claim any performance things for itself. In this initial implementation of zap,
|
claim any performance fame for itself. In this initial implementation of zap,
|
||||||
I didn't care about optimizations at all.
|
I didn't care about optimizations at all.
|
||||||
|
|
||||||
But, how fast is it? Being blazingly fast is relative. When compared with a
|
But, how fast is it? Being blazingly fast is relative. When compared with a
|
||||||
|
@ -82,6 +85,7 @@ $ cd zap
|
||||||
$ zig build run-hello
|
$ zig build run-hello
|
||||||
$ # open http://localhost:3000 in your browser
|
$ # open http://localhost:3000 in your browser
|
||||||
```
|
```
|
||||||
|
|
||||||
... and open [http://localhost:3000](http://locahhost:3000) in your browser.
|
... and open [http://localhost:3000](http://locahhost:3000) in your browser.
|
||||||
|
|
||||||
## Using ⚡zap⚡ in your own projects
|
## Using ⚡zap⚡ in your own projects
|
||||||
|
@ -124,7 +128,35 @@ In the `build` function, add the following before `exe.install()`:
|
||||||
zap_builder.addZap(exe, "./libs/zap/") catch unreachable;
|
zap_builder.addZap(exe, "./libs/zap/") catch unreachable;
|
||||||
```
|
```
|
||||||
|
|
||||||
From then on, you can use the zap package in your project. Check out the examples to see how to use zap.
|
From then on, you can use the zap package in your project. Check out the
|
||||||
|
examples to see how to use zap.
|
||||||
|
|
||||||
|
## Contribute to ⚡zap⚡ - blazingly fast
|
||||||
|
|
||||||
|
At the current time, I can only add to zap what I need for my personal and
|
||||||
|
professional projects. While this happens **blazingly fast**, some if not all
|
||||||
|
nice-to-have additions will have to wait. You are very welcome to help make the
|
||||||
|
world a blazingly fast place by providing patches or pull requests, add
|
||||||
|
documentation or examples, or interesting issues and bug reports - you'll know
|
||||||
|
what to do when you receive your calling 👼.
|
||||||
|
|
||||||
|
Check out [CONTRIBUTING.md](CONTRIBUTING.md) for more details.
|
||||||
|
|
||||||
|
See also [introducing.md](introducing.md) for more on the state and progress of
|
||||||
|
this project.
|
||||||
|
|
||||||
|
You can also reach me on [the zig showtime discord
|
||||||
|
server](https://discord.gg/CBzE3VMb) under the handle renerocksai
|
||||||
|
(renerocksai#1894).
|
||||||
|
|
||||||
|
## Support ⚡zap⚡
|
||||||
|
|
||||||
|
Being blazingly fast requires a constant feed of caffeine. I usually manage to
|
||||||
|
provide that to myself for myself. However, to support keeping the juices
|
||||||
|
flowing and putting a smile on my face and that warm and cozy feeling into my
|
||||||
|
heart, you can always [buy me a coffee](https://buymeacoffee.com/renerocksai)
|
||||||
|
☕. All donations are welcomed 🙏 blazingly fast! That being said, just saying
|
||||||
|
"hi" also works wonders with the smiles, warmth, and coziness 😊.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|
194
introducing.md
Normal file
194
introducing.md
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
# Introducing ⚡zap⚡ - blazingly fast backends in zig
|
||||||
|
|
||||||
|
Zap is intended to become my [zig](https://ziglang.org) replacement for the
|
||||||
|
kind of REST APIs I used to write in [python](https://python.org) with
|
||||||
|
[Flask](https://flask.palletsprojects.com) and
|
||||||
|
[mongodb](https://www.mongodb.com), etc.
|
||||||
|
|
||||||
|
What I need for that is a blazingly fast, robust HTTP server that I can use with
|
||||||
|
zig. While facil.io supports TLS, I don't care about HTTPS. In production, I use
|
||||||
|
[nginx](https://www.nginx.com) as a reverse proxy anyway.
|
||||||
|
|
||||||
|
Zap wraps and patches [facil.io - the C web application
|
||||||
|
framework](https://facil.io).
|
||||||
|
|
||||||
|
At the time of writing, ZAP is only a few days old and aims to be:
|
||||||
|
|
||||||
|
- **robust**
|
||||||
|
- **fast**
|
||||||
|
- **minimal**
|
||||||
|
|
||||||
|
**Side-note:**
|
||||||
|
It never ceases to amaze me how productive I can be in zig, eventhough I am
|
||||||
|
still considering myself to be a newbie. Sometimes, it's almost like writing
|
||||||
|
python but with all the nice speed and guarantees that zig gives you. Also, the
|
||||||
|
C integration abilities of zig are just phenomenal! I am super excited about
|
||||||
|
zig's future!
|
||||||
|
|
||||||
|
**⚡ZAP⚡ IS SUPER ALPHA**
|
||||||
|
|
||||||
|
_Under the hood, everything is super robust and fast. My zig wrappers are fresh,
|
||||||
|
juicy, and alpha._
|
||||||
|
|
||||||
|
Here's what works:
|
||||||
|
|
||||||
|
- **Super easy build process**: zap's `build.zig` fetches facilio's git
|
||||||
|
sub-module, applies a patch to its logging for microsecond precision, and then
|
||||||
|
builds and optionally runs everything.
|
||||||
|
- _tested on Linux and macOS (arm, M1)_
|
||||||
|
- **[hello](https://github.com/renerocksai/zap/blob/master/examples/hello/hello.zig)**:
|
||||||
|
welcomes you with some static HTML
|
||||||
|
- **[routes](https://github.com/renerocksai/zap/blob/master/examples/routes/routes.zig)**:
|
||||||
|
a super easy example dispatching on the HTTP path
|
||||||
|
- **[serve](https://github.com/renerocksai/zap/blob/master/examples/serve/serve.zig)**:
|
||||||
|
the traditional static web server with optional dynamic request handling
|
||||||
|
- **[hello_json](https://github.com/renerocksai/zap/blob/master/examples/hello_json/hello_json.zig)**:
|
||||||
|
serves you json dependent on HTTP path
|
||||||
|
- **[endpoints](https://github.com/renerocksai/zap/blob/master/examples/endpoints/)**:
|
||||||
|
a simple JSON REST API example featuring a `/users` endpoint for
|
||||||
|
PUTting/DELETE-ing/GET-ting/POST-ing users and a `/list` endpoint returning
|
||||||
|
the entire user list on GET, together with a static HTML and JavaScript
|
||||||
|
frontend to play around with.
|
||||||
|
|
||||||
|
|
||||||
|
If you want to take it for a quick spin:
|
||||||
|
```shell
|
||||||
|
$ git clone https://github.com/renerocksai/zap.git
|
||||||
|
$ cd zap
|
||||||
|
$ zig build run-hello
|
||||||
|
$ # open http://localhost:3000 in your browser
|
||||||
|
```
|
||||||
|
See [the README](https://github.com/renerocksai/zap) for how easy it is to get
|
||||||
|
started, how to run the examples, and how to use zap in your own projects.
|
||||||
|
|
||||||
|
I'll continue wrapping more of facil.io's functionality and adding stuff to zap
|
||||||
|
to a point where I can use it as the JSON REST API backend for real research
|
||||||
|
projects, serving thousands of concurrent clients. Now that the endpoint example
|
||||||
|
works, ZAP has actually become pretty usable to me.
|
||||||
|
|
||||||
|
Now, on to the guiding principles of Zap.
|
||||||
|
|
||||||
|
## robust
|
||||||
|
|
||||||
|
A common recommendation for doing web stuff in zig is to write the actual HTTP
|
||||||
|
server in Go, and use zig for the real work. While there is a selection of
|
||||||
|
notable and cool HTTP server implementations written in zig out there, at the
|
||||||
|
time of writing, most of them seem to a) depend on zig's async facilities which
|
||||||
|
are unsupported until ca. April 2023 when async will return to the self-hosted
|
||||||
|
compiler, and b) have not matured to a point where **I** feel safe using them in
|
||||||
|
production. These are all my opionions and they could be totally wrong.
|
||||||
|
|
||||||
|
However, when I conduct my next online research experiment with thousands of
|
||||||
|
concurrent clients, I cannot afford to run into potential maturity-problems of
|
||||||
|
the HTTP server. These projects typically feature a you-get-one-shot process
|
||||||
|
with little room for errors or re-tries.
|
||||||
|
|
||||||
|
With zap, if something should go wrong, at least I'd be close enough to the
|
||||||
|
source-code to, hopefully, be able to fix it in production. With that out of the
|
||||||
|
way, I am super confident that facil.io is very mature compared to many of the
|
||||||
|
alternatives. My `wrk` tests also look promising.
|
||||||
|
|
||||||
|
I intend to add app-specific performance tests, e.g. stress-testing the endpoint
|
||||||
|
example, to make sure the zap endpoint framework is able to sustain a high load
|
||||||
|
without running into performance or memory problems. That will be interesting.
|
||||||
|
|
||||||
|
|
||||||
|
## ⚡blazingly fast⚡
|
||||||
|
|
||||||
|
Claiming to be blazingly fast is the new black. At least, zap doesn't slow you
|
||||||
|
down and if your server performs poorly, it's probably not exactly zap's fault.
|
||||||
|
Zap relies on the [facil.io](https://facil.io) framework and so it can't really
|
||||||
|
claim any performance fame for itself. In this initial implementation of zap, I
|
||||||
|
didn't care about optimizations at all.
|
||||||
|
|
||||||
|
But, how fast is it? Being blazingly fast is relative. When compared with a
|
||||||
|
simple GO HTTP server, a simple zig zap HTTP server performed really good on my
|
||||||
|
machine:
|
||||||
|
|
||||||
|
- zig zap was nearly 30% faster than GO
|
||||||
|
- zig zap had over 50% more throughput than GO
|
||||||
|
|
||||||
|
I intentionally only tested static HTTP output, as that seemed to be the best
|
||||||
|
common ground of all test subjects to me. The measurements were for just getting
|
||||||
|
a ballpark baseline anyway.
|
||||||
|
|
||||||
|
**Update**: I was intrigued comparing to a basic rust HTTP server.
|
||||||
|
Unfortunately, knowing nothing at all about rust, I couldn't find a simple,
|
||||||
|
just-a-few-lines one like in Go and Python right away and hence tried to go for
|
||||||
|
the one in the book [The Rust Programming
|
||||||
|
Language](https://doc.rust-lang.org/book/ch20-00-final-project-a-web-server.html).
|
||||||
|
Wanting it to be of a somewhat fair comparison, I opted for the multi-threaded
|
||||||
|
example. It didn't work out-of-the-book, but I got it to work (essentially, by
|
||||||
|
commenting out all "print" statements) and changed it to not read files but
|
||||||
|
outputting static text just like the other examples. **Maybe someone with rust
|
||||||
|
experience** can have a look at my [wrk/rust/hello](wrk/rust/hello) code and
|
||||||
|
tell me why it is surprisingly 'slow', as I expected it to be faster than or at
|
||||||
|
least on-par with the basic Go example. I'll enable the GitHub discussions for
|
||||||
|
this matter. My suspicion is bad performance of the mutexes.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
So, being somewhere in the ballpark of basic GO performance, zig zap seems to be
|
||||||
|
... of reasonable performance 😎.
|
||||||
|
|
||||||
|
See more details in
|
||||||
|
[blazingly-fast.md](https://github.com/renerocksai/zap/blob/master/blazingly-fast.md).
|
||||||
|
|
||||||
|
## minimal
|
||||||
|
|
||||||
|
Zap is minimal by necessity. I only (have time to) add what I need - for serving
|
||||||
|
REST APIs and HTML. The primary use-case are frontends that I wrote that
|
||||||
|
communicate with my APIs. Hence, the focus is more on getting stuff done rather
|
||||||
|
than conforming to every standard there is. Even though facilio is able to
|
||||||
|
support TLS, I don't care about that - at least for now. Also, if you present
|
||||||
|
`404 - File not found` as human-readable HTML to the user, nobody forces you to
|
||||||
|
also set the status code to 404, so it can be OK to spare those nanoseconds.
|
||||||
|
Gotta go fast!
|
||||||
|
|
||||||
|
Facilio comes with Mustache parsing, TLS, websockets, redis support, concurrency
|
||||||
|
stuff, Base64 support, logging facilities, pub/sub / cluster messages API, hash
|
||||||
|
algorithm implementations, its own memory allocator, and so forth. It is really
|
||||||
|
an amazing project!
|
||||||
|
|
||||||
|
On the lower level, you can use all of the above by working with `zap.C`. I'll
|
||||||
|
zig-wrap what I need for my projects first, before adding fancy stuff.
|
||||||
|
|
||||||
|
Also, there are nice and well-typed zig implementations for some of the above
|
||||||
|
extra functionalities, and zap-wrapping them needs careful consideration. Might
|
||||||
|
not be worth the extra effort. Performance / out-of-the-box integration might be
|
||||||
|
arguments pro wrapping them in zap.
|
||||||
|
|
||||||
|
## wrapping up - zig is WYSIWYG code
|
||||||
|
|
||||||
|
I am super excited about both zig and zap's future. I am still impressed by how
|
||||||
|
easy it is to integrate a C codebase into a zig project, then benefiting from
|
||||||
|
and building on top of a battle-tested high-performance C code. Additionally,
|
||||||
|
with zig you get C-like performance with almost Python-like comfort. And be sure
|
||||||
|
no exception is trying to get you when you least expect it. No hidden
|
||||||
|
allocations, no hidden control-flows, how cool is that? **WYSIWYG code!**
|
||||||
|
|
||||||
|
Provided that the incorporated C code is well-written and -tested, WYSIWYG even
|
||||||
|
holds true for combined Zig and C projects.
|
||||||
|
|
||||||
|
You can truly build on the soulders of giants here. Mind you, it took me less
|
||||||
|
than a week to arrive at the current state of zap where I am confident that I
|
||||||
|
can already use it to write the one or other REST API with it and, after
|
||||||
|
stress-testing, just move it into production - from merely researching Zig and C
|
||||||
|
web frameworks a few days ago.
|
||||||
|
|
||||||
|
Oh, and have I mentioned Zig's built-in build system and testing framework?
|
||||||
|
Those are both super amazing and super convenient. `zig build` is so much more
|
||||||
|
useful than `make` (which I quite like to be honest). And `zig test` is just
|
||||||
|
amazing, too. Zig's physical code layout: which file is located where and how
|
||||||
|
can it be built, imported, tested - it all makes so much sense. Such a coherent,
|
||||||
|
pleasant experience.
|
||||||
|
|
||||||
|
Looking forward, I am also tempted to try adding some log-and-replay facilities
|
||||||
|
as a kind of backup for when things go wrong. I wouldn't be confident to attemt
|
||||||
|
such things in C because I'd view them as being too much work; too much could go
|
||||||
|
wrong. But with Zig, I am rather excited about the possibilities that open up
|
||||||
|
and eager to try such things.
|
||||||
|
|
||||||
|
To great justice!
|
Loading…
Add table
Reference in a new issue