rongcuid / reforum

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Reforum

Goals

  • Single server, single program, period

  • Optimize later

Roadmap

  • ❏ Version 0.9

    • ✓ Standalone authentication

      • ❏ Login/logout/sessions

      • ❏ Registration/change password/recovery

    • ✓ Role based authorization

    • ❏ CRUD

I will stop here, and go investigate some more tech stacks. However, if I feel like this is the best stack I’ve got, then I will continue with the roadmap.

  • ❏ Version 1.0

    • ❏ Refactor types

    • ❏ Refactor errors

    • ❏ Unit testing

    • ❏ Documentation

  • ❏ Version 1.1

    • ❏ HTML templates

    • ❏ I18N

    • ❏ Front page

    • ❏ Pinned topics

  • ❏ Version 1.2

    • ❏ Finer-grained authorization

    • ❏ Tags

    • ❏ Search

    • ❏ HTMX flow?

  • ❏ Version 1.3

    • ❏ Finer-grained moderation

  • ❏ Version 2.0

    • ❏ ORY Kratos

    • ❏ Asciidoc

User Story

Basic Interactions

Account Actions

  • ❏ There is only one site administrator

  • ❏ The user may wipe his/her account, deleting every topics/posts/replies from the database

    • ❏ Optionally require moderator approval

    • ❏ Moderators wiping their own account always require admin approval

    • ❏ If user has been a moderator, this fact would persist in the past_moderators table

    • ❏ Only the user himself/herself or the site administrator may wipe the account

    • ❏ If the user has been a moderator and has modified others' content, the log persist as UID

Soft Deletion

  • ❏ Topics and posts are never deleted from database, unless their authors' accounts are wiped

  • ❏ Replies are actually deleted

Authentication

Authorization

Moderation

Administration

  • ❏ Good tracing

    • ✓ Log all requests and response codes

    • ✓ Latency traces

  • ❏ Rate limiting

    • ❏ Intervals between posts

    • ❏ Intervals between views

Experience Report

Rust

You need to be really determined before thinking about using Rust. Rust language is extremely powerful. I’d say, excellent blend of performance, safety, and expressiveness. Imperative styles and functional styles are all covered.

However, it comes with very high upfront cost: scaffolding the project, reserving Gigabytes of space for target/, preparing for minute-long Rust Analyzer checks, and a very hot CPU. Unless you really need that bit of performance/memory footprint, use Rust only when you plan to build something substantial, or when somebody else makes a super easy to use framework. I would consider this monolith forum "substantial".

Performance? Yeah, it is simply excellent. I am not even trying, because I am cloning stuff very liberally.

Other languages

I went on to try Go too. I must say its compiles magnitudes faster. Rust is probably not going to beat this record ever, because Rust is just so complex a language. Yes, with procedural macros, traits, generics, and lifetime, Rust is like a supercharged mix of Lisp, ML, and C++.

Rust’s error handling seems to be much more powerful and ergonomic, but async/await cannot beat Go’s in ergonomics. Of course, Go is designed for concurrency, and Rust is not. But whatever language it is, the current Middleware architecture just looks so much like constructing Monad Transformer by hand.

Nobody can beat Haskell for dealing with Monads, and Haskell has green threads as good as Go. Honestly, the only reason I am not using Haskell is that its support of cross compiling is still terrible. I have to target X86, ARM, or possibly WASM, so I need a compiler like Rust/Go which can do it. No, I am not compiling an entire web server on a Raspberry Pi.

It’s not the Language. It’s the Runtime.

Sea-ORM

  • The migrations are quite unreadable.

    • Each table’s definition easily takes up hundreds of lines with framework-defined identifiers everywhere

    • If you think in raw SQL it is difficult to see all relations, in this migration script it is even harder, because they take up 10 times more space

    • These migrations should be generated procedurally. The Entity definitions are much easier to read

  • The manual entity generation step is suboptimal

    • Again, I would prefer to generate migrations from entities, not the other way around

  • The automatic generation for SQLite gives wrong types

    • i32 instead of i64

    • String instead of DateTimeUtc

    • INSERT ON CONFLICT not supported for sqlite

  • Sea-Query statements generally very verbose and hard to read, and I cannot set it up stand-alone with rusqlite

SQLite

  • Rusqlite does not support async

  • Deadpool for pooling has some…​ issues

    • Unlike sqlx, there cannot be async transactions

    • InteractError is a bit unergonomic when working with other errors (because of !Send)

  • sqlx does not support the full functionality of SQLite (hooks, functions, etc)

About


Languages

Language:Rust 100.0%