1
0
Fork 0
mirror of https://github.com/zigzap/zap.git synced 2025-10-20 15:14:08 +00:00

updated READE, CONTRIBUTING

This commit is contained in:
Rene Schallner 2023-01-15 18:55:01 +01:00
parent 307543c5a0
commit 0f135a2ff4
3 changed files with 264 additions and 2 deletions

36
CONTRIBUTING.md Normal file
View 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.

View file

@ -14,6 +14,9 @@ framework](https://facil.io).
**⚡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 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
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 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.
But, how fast is it? Being blazingly fast is relative. When compared with a
@ -82,6 +85,7 @@ $ cd zap
$ zig build run-hello
$ # open http://localhost:3000 in your browser
```
... and open [http://localhost:3000](http://locahhost:3000) in your browser.
## 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;
```
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

194
introducing.md Normal file
View 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.
![](https://raw.githubusercontent.com/renerocksai/zap/master/wrk_table_summary.png)
![](https://raw.githubusercontent.com/renerocksai/zap/master/wrk_charts_summary.png)
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!