Uuuu miao, che dolore il software... 😰
L'ho detto fin troppo poco o forse no, che sto da qualche giorno o giù di lì pensando ad una pazzia assoluta da programmare... e in effetti, forse è ciò che dall'inizio dell'anno mi sta lievemente distraendo piano piano, al punto che nemmeno sto continuando gli altri progetti, nonché sto cadendo sempre più in basso per quanto riguarda le mie altre responsabilità di vita, ma quest'ultimo è un altro fatto... 😱
Beh, disperazione a parte, forse ora ne posso anche parlare qui, di questa mattanza... perché non solo ho le idee un po' più chiare, ma ho iniziato a programmare qualcosina di pratico e si spera meno scassone a riguardo, che potrebbe finire in produzione... 🤨
E in realtà non so comunque bene se e come andrà a finire, perché neanche le entità del cielo possono in realtà sapere se domani, o dopodomani, o comunque a brevissimo termine non mi sarò già seccata e avrò parzialmente dimenticato tutto, perché questa robina non è proprio semplicissima... ma in tal caso pazienza, direi (...e, con me ce ne vuole tanta). 🥴
Lascio il codice ancora appezzottato e poco comprensibile qui, allora, per chi vuole tirare a indovinare senza sapere... probabilmente, azzeccandoci anche non capendo niente del codice in sé, qualora mi si tenga abbastanza d'occhio da avere un certo sguardo d'insieme decente sulle mie più attuali fissazioni tecnologiche giornaliere... e così, nel mentre, io ho anche il tempo di trovare le parole sia più complicate che più semplici possibili per spiegarmi: https://gitlab.com/octospacc/noteserv. 😈
(Per giunta... con questo coso ne sto approfittando per provare Go, cosa che non ho mai davvero fatto, ma a questo punto mi tocca, perché sia TypeScript che Python che PHP, con l'uso di risorse, manderanno il mio server in coma di questo passo... chissà se me ne pentirò.)
Tenterò di spiegarmi su questa cazzata una volta per tutte ora, prima che il sonno mi mangi (che, stasera, per qualche motivo a quest'ora ne ho un po'... sperando non sparisca!!!), ma soprattutto prima che un qualche inaspettato momento di lucidità mi colpisca, facendomi vergognare anche dell'idea stessa, dai... 🤗
Quello che avrei in mente di fare è, come l'ho pensato descritto ieri... un backend di note e/o blogging multiutente che sia fighissimo e flessibile e, importante per la mia pazzia, basato su file Markdown!!! (Flat-file.) 💥
Dove ciò non significa un'intera piattaforma social federata elaborata, e nemmeno un CMS web con tutte le sue cose classiche, ma (almeno come scopo iniziale) un puro backend più o meno funzionale e compatto per salvare note lunghe o corte, allegare file, e avere tutto condiviso nel contesto dell'istanza stessa, tenuto privato, acceduto tramite API e vari frontend, replicato immediatamente su piattaforme terze con i soliti giochetti, o riutilizzato attraverso generatori di siti statici... le possibilità sono infinite. 🥰
Detto in modo forse meno astratto, e a cui forse anche i più dormienti potranno quindi ricondurre il senso della mia necessità, dopo le tante volte che ho parlato delle mancanzine a livello di backend che frenano Misskey dall'essere la piattaforma di note personali+social migliore possibile per me (ma così come anche Memos, che invece non è social)... ☝️
Praticamente, qui ora sto facendo un server che copia (in parte) la API di Misskey, e con cui infatti posso connettermi con qualsiasi frontend Misskey, però dietro le quinte il tutto non usa PostgreSQL, bensì i file sparsi sul file system, evviva! Ovviamente, il flat-file non è l'unica cosa che cambia le carte in tavola, bensì in più qui avrei la possibilità di impostare date arbitrarie per le note, di dividerle in categorie per cui si possono gestire secondo altri criteri, averne di non in elenco, e chissà che altro di non troppo indecente che mi verrà in mente a lungo andare, e che al momento i software già fatti comunque non mi offrono. 😏
...In realtà, poi, in tutto questo Misskey non ci azzecca una mazza, perché 'sto affare non è un fork, non è una riscrittura, ma è proprio una cosa a sé, che lavora ed esiste per conto suo... e sì, potrebbe parzialmente sostituire Sharkey in produzione per me, ma non vuol dire niente. 👾
Il punto è che la client API di Misskey la trovo ben progettata, e di base già adatta a ciò che mi serve, e quindi adottandola non devo sbattermi a progettare io una API da zero... così come, adottando quella anziché una mai esistita, ho già ben 2 frontend buoni che funzionano con questo server, che altrimenti al momento non ha (e forse mai avrà, perché a quel punto sarebbe solo lavoro inutile) una sua interfaccia... quindi, non solo sviluppo con meno rogne, ma poi in teoria ci godo pure meglio, credo. 🧨
In questa schermatina già si vede la mia grande magagna, in sintesi... il frontend di Sharkey connesso al mio server spaccato scritto da zero che, seppur non molto correttamente, carica delle note che sono scritte su file Markdown molto bizzarramente, ma non casualmente, organizzati... e oh, se non mi perdo per la via, penso che l'idea potrebbe essere promettente. 😇
Certo, c'è anche da dire che il sistema flat-file complica non poco lo sviluppo di un backend di note threadate multiutente, perché per motivi di scalabilità il sistema deve comunque usare un database come cache, altrimenti diventa rapidamente un troiaio, ma questo significa che faccio praticamente lavoro doppio... forse per questo idee del genere non si vedono in giro... però che dobbiamo fare: evil octo pretende che questo sia uno dei requisiti, e quindi niente, mi tocca soffrire ed implementare; mannaggia al codice non magico. 😭
Comunque oooh... mi sa che devo ribadire quanto casino sta uscendo fuori in questo affare per via di questa assurda mistura operativa tra flat-file e database che serve fare... o forse boh, magari i dettagli di ciò nello specifico saranno meglio visti un'altra volta, quando saranno ironicamente ancora più incasinati, ma contemporaneamente anche più certi... 🤥
Mentre adesso, invece, ma infatti per giunta, stavo pensando al casino che mi sta uscendo fuori per stabilizzarmi su questa cosa... perché, se da un lato c'è la difficoltà dello sdoppiamento delle cose che per ora lasciamo stare, dall'altro c'è la solita tiritera per cui io mi bisticcio coi database. 😳
Ora penso di aver deciso definitivamente di usare SQLite come database, che da un lato, come accennato, mi serve come cache, praticamente per tenere degli indici di dati che altrimenti sarebbe indecentissimo riprendere dal disco ogni volta... ma, mi sa mi sa che mi servirà per tenere anche dati secondari che su flat-file non hanno proprio senso, perché tanto non sono da modificare a mano, e comunque dovrei sennò cacare in DB... per esempio, i token di sessione associati ad ogni utente, che qui stanno quindi nella loro tabellina per bene (non quella mostrata in foto)... 🔥
E per di sopra, ci metto poi Bun come ORM, che sembra accettabile, altrimenti rapidamente esplodo... 💥
La cosa (non) divertente qui però, che chi vuole insultarmi può notare meglio andando a vedere i commit sulla repo, è che ci ho messo da ieri fino ad ora per stabilizzarmi su questa idea, e quindi finalmente continuare ad andare avanti con bestemmie limitate ad implementare le funzioni del server... 🤥
Perché, inizialmente, pensavo un database chiave-valore fosse sufficiente, e allora ho provato un certo Bolt... che però, oltre ad avere una API abbastanza cagata (decisamente non bella immediata e semplice, come invece io pretendo e mi aspetto avendo usato certe robine tra Python e JavaScript), mi sono resa conto non essere proprio il caso, perché per certe query che in questo programma mi servono un DB non-relazionale è proprio un suicidio... 🎳
Ma poi, tolto di mezzo questo, e passato il focus su SQLite come doveva essere fin dall'inizio, per colpa del fatto che ho voluto credere a ChatGPT, non ho cercato da subito un ORM, bensì ho usato inizialmente l'interfaccia SQL grezza... ma no, anche qui è uno schifo, che è tutto da interfacciare a mano con le stringhe di merda e le query non sono nemmeno syncate con le struct che ho definito in Go, quindi la comodità dei tipi definiti se ne va bella a quel paese... 💤
Quindi boh, immaginate come stavo bene comoda ad impazzire fino a qualche ora fa, quando ho scattato questa schermata prima di aver finalmente riordinato il codice... ben 2 database, e 3 diversi tipi di interfacce a questi in totale, presenti e usati contemporaneamente, in un programma che ancora non fa neanche niente di pronto: un file di centinaia di righe con, tra le altre cose, tante funzioni duplicate per fare la stessa cosa databasiaca per vie diverse, fino a prima che buttassi via la spazzatura... wow!!! 🥰
Per fortuna, almeno, per ora lo schifo è (stato) tutto qui, non c'è altro... e questo è solo un esempio tanto stupido quanto importante di un dietro le quinte di quei momenti in cui il codice NON è magico, neanche minimamente, bensì è solo spaghetti conditi con veleno, o qualcosa del genere... roba che le altre ragazze magiche per vergogna non raccontano, insomma. 🦑
Rispostando per ancora un attimino la mia attenzione descrittiva a questo mio sempre più magico $[sparkle serverino affarino notino], che dopo ancora altra lunga programmazione in realtà credo ora supporti il minimo di funzioni di base necessarie ad essere quantomeno già testabile a livello personale, ma ehh, gli spiriti mi devono dare il permesso di testare più meglio assai nella pratica in produzione, penso ci sia già un'altra cosa bella fighina del design di cui posso e devo parlare... 🥰
E allora, prima che subentrino le gigantesche palle... che con me è sempre più una certezza che una possibilità, quando ho qualcosa che sviluppo per giorni e giorni, ma lo scope iniziale è così grosso che non riesco ad arrivare subito ad un MVP, quindi mi scoccio, quindi mi scordo, e quindi mi ritrovo che altro non ho fatto che creare del codice marciscente (anche se, il tempo non è mai perso a scrivere merdatine, perché sviluppando si impara sempre qualcosa di nuovo), volevo dire tutto sul sistema degli ID che il sistema usa per memorizzare, ed identificare, i vari dati... note, utenti, file, e le prossime robe. 🎯
Riprendendo da Misskey sia la API nel pratico, che il design tecnico delle robe in astratto, ogni elemento indipendentemente indirizzabile del sistema ha un ID alfanumerico univoco, che non deve cambiare mai, e che codifica anche il tempo di creazione, in stringhe che sono appunto ordinabili naturalmente per il tempo... ☝️
La differenza tosta, però, è che io uso degli ID che sono più lunghi, perché contengono anche 128 bit (16 byte) di entropia, random... e questo perché, come detto, programmo di supportare note e cose varie che siano "non in elenco", cioè che non appaiono nelle liste pubbliche, ma che siano accessibili conoscendo l'URL, senza necessariamente fare cose strane tipo implementare token di condivisione, che bah... praticamente, come fa YouTube, i cui ID dei video però hanno solo 64 bit di entropia; e quindi direi pure che se quelli sono ritenuti abbastanza sicuri contro il bruteforcing, questi miei sono perfetti. 👌
Nella pratica, ho usato dunque i KSUID, con la rispettiva libreria per Go, e non UUIDv7 standard come avevo in mente inizialmente... perché boh, mi sembra meglio, visto il mio requisito di sopra, avendo più entropia (anziché 74 bit), anche se meno spazio per il tempo (32 bit, cioè 4 byte, anziché 48 bit)... che però sarà un problema solo tra 100 anni, quindi ora non freca. 🍆
KSUID poi avrebbe anche un altro vantaggio, cioè che genera già stringhe di caratteri alfanumerici belline senza simboli (Base62), a differenza di UUID che richiederebbe altro encoding... ma, in realtà, nel mio caso questo è inutile, perché faccio comunque del mio encoding, in Base58... e questo perché, detto che la lunghezza rimane praticamente uguale (da 27 caratteri certi passa a 27-28), Base58 elimina i caratteri visivamente ambigui (0, O, I, l), permettendo quindi di trascrivere gli ID, e quindi gli URL delle note, persino a manina senza bestemmiare, qualora dovesse servire... adoro!!!! 😆
E sì, comunque sono lunghetti, comparabili forse alle piattaforme che usano ID numerici (Mastodon, X, Pignio...) e non eleganti quanto quelli di Misskey... ma, visti tutti i requisiti, a me mi pare un compromesso senza compromessi, diciamo così.
Probabilmente, detto tutto ciò, è più strano e complicato a spiegarsi che a vedersi, ad esperienziarsi, o anche a leggersi... perché infatti, nella pratica, è tutto così semplice ed efficace e buono che, per ora, tutto il mio codice di utilità relativo agli ID è in un file di appena 30 righe; gnam! https://gitlab.com/octospacc/noteserv/-/blob/main/utils/ids.go 🎃
E allora... mentre del file system dovrò parlare più avanti, qui regalo un'anteprima di com'è l'albero dei file con questi ID, così da avere già un'idea più ampia:
data
├───notes
│ ├───JjhGRzcm4DS55hFb8Ecn9p4rMLv
│ │ └───default
│ │ JjthzpQpKsVcRNd8HdSo9o1VtMw.md
│ │ Jjw8J4tbPcKnfkikrSvBzGFmsqb.md
│ └───JjV5dxN2oGckihMASu9AZSXXPr5
│ └───default
│ JjxhuAiwzadqPuVegB5JHNH27vp.md
└───users
JjhGRzcm4DS55hFb8Ecn9p4rMLv.md
JjV5dxN2oGckihMASu9AZSXXPr5.md