Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use NATS #8118

Open
wants to merge 245 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
245 commits
Select commit Hold shift + click to select a range
b264ca2
nats: proof of concept experiments
williamstein Jan 11, 2025
20210f0
nats POC: proxying nats websocket server using node-proxy
williamstein Jan 12, 2025
e60daf6
nats -- api/v2 via nats POC
williamstein Jan 12, 2025
0a4137f
Merge branch 'master' into nats
williamstein Jan 18, 2025
0d3f772
Merge branch 'master' into nats
williamstein Jan 19, 2025
d76b8c4
Merge branch 'master' into nats
williamstein Jan 19, 2025
3615482
nats: add proof of concept involving the project
williamstein Jan 20, 2025
f5ed6b8
nats: use queue group for hub.api POC server
williamstein Jan 20, 2025
ce70f06
Merge branch 'master' into nats
williamstein Jan 20, 2025
5e84190
nats POC: switching to using "ability to publish to the subject" to p…
williamstein Jan 20, 2025
52a18ad
NATS POC - work in progress exploring how to do auth
williamstein Jan 20, 2025
9cd0cd5
NATS POC -- figured out *how* to securely do auth with a JWT from a b…
williamstein Jan 20, 2025
7409e81
nats: implement creating nats user associated to account, including a…
williamstein Jan 21, 2025
737fb73
nats: setting nats jwt cookie automatically and in the right place
williamstein Jan 21, 2025
38de8bd
nats: automate pushing/pulling local nsc with cluster
williamstein Jan 21, 2025
42c8864
nats: provide JWT to project, let project connect, get it to do somet…
williamstein Jan 21, 2025
687a8fd
nats: work in progress implementing proof of concept terminal to see …
williamstein Jan 22, 2025
59da3c9
nats: working terminal communication (very basic but works)
williamstein Jan 22, 2025
cc955ea
nats: terminal proof of concept
williamstein Jan 22, 2025
e884b4f
nats: sys --> cocalc account
williamstein Jan 22, 2025
5fdbb79
nats: work in progress using jetstream for terminals
williamstein Jan 22, 2025
277b139
nats - move terminal jetstream creation to project; avoid junk charac…
williamstein Jan 23, 2025
362568e
remove manifest in DEBUG mode (since it's constantly failing and the …
williamstein Jan 23, 2025
8e203ac
NATS: reimplement terminal initialization... yet again!
williamstein Jan 23, 2025
bdb9053
nats terminal -- partial messaging for resizing the terminal
williamstein Jan 23, 2025
a66fdf6
nats terminal: properly doing resizing
williamstein Jan 23, 2025
5a6f48e
nats terminal: implement open/close command (not happy about it)
williamstein Jan 23, 2025
9225889
nats terminal: use a different subject for the commands
williamstein Jan 23, 2025
2f3068c
nats terminal: use pending field of mesg to better know when terminal…
williamstein Jan 23, 2025
6a14bf8
nats: syncstrings first POC
williamstein Jan 24, 2025
244eebb
nats: synctable
williamstein Jan 24, 2025
a5787cc
nats synctable -- get all
williamstein Jan 24, 2025
b1187b2
nats: add listings table
williamstein Jan 24, 2025
041e5bb
nats: use single kv store for each project
williamstein Jan 24, 2025
92e8d35
reformat sorted-patch-list to use arrow functions
williamstein Jan 24, 2025
b2d6254
Merge branch 'master' into nats
williamstein Jan 24, 2025
6e32715
nats patches stream -- work in progress
williamstein Jan 24, 2025
f6901c0
nats: quick broken proof of concept test of file editing using nats...
williamstein Jan 25, 2025
ad7807c
nats collab editing proof of concept -- fix some issues so it works
williamstein Jan 25, 2025
f03c3b0
nats sync: a little bit of saving
williamstein Jan 25, 2025
2fa9fd2
nats: one subject for all patches in a project
williamstein Jan 25, 2025
fb4b4a4
nats: create a new package
williamstein Jan 25, 2025
419067f
nats: work in progress figuring out a better type-checked way to do R…
williamstein Jan 25, 2025
aa22718
nats: starting to add db service
williamstein Jan 26, 2025
b0b36bf
nats api: a little bit of refactoring
williamstein Jan 26, 2025
5315d47
nats: foundations for changefeeds
williamstein Jan 26, 2025
08e80a8
nats: organizing startup/config
williamstein Jan 26, 2025
ea1669b
nats synctable: added support for atomic tables, which we'll use for …
williamstein Jan 26, 2025
a6a04e4
nats database changefeeds: one per query
williamstein Jan 26, 2025
4e4fda0
nats db synctable: automatically stop
williamstein Jan 26, 2025
f7fbc45
organize sync changefeed code
williamstein Jan 26, 2025
cee658c
nats synctables: got page to load and the non-project-specific tables…
williamstein Jan 26, 2025
854ec97
nats: fix collab editing
williamstein Jan 26, 2025
9a69f84
clean up use of sha1 (js version all imported from @cocalc/util); als…
williamstein Jan 27, 2025
b33ec24
more sha1 cleanup
williamstein Jan 27, 2025
7d8b198
nats api: refactoring
williamstein Jan 27, 2025
4ed5f3f
nats: refactoring hub api -- rewrite time functionality to use NATS i…
williamstein Jan 27, 2025
c37f6c8
Merge branch 'master' into nats
williamstein Jan 28, 2025
89e230c
proper pnpm-lock update
williamstein Jan 28, 2025
c78decf
Merge branch 'master' into nats
williamstein Jan 28, 2025
916987e
nats: automate installation of nats, nsc and nats-server on a given host
williamstein Jan 28, 2025
534cb21
nats: automate install/configuration/auth at least for dev mode
williamstein Jan 28, 2025
61ca262
nats: set variables to disable use of nats everywhere by default
williamstein Jan 29, 2025
ab916b8
nats: use nats for project websocket request/reply api (totally autom…
williamstein Jan 29, 2025
1c50f13
nats: automate adding permissions when connecting to project
williamstein Jan 29, 2025
d920317
nats: shorter ping times for now so nats clients start working again …
williamstein Jan 29, 2025
4463105
nats: working on implementing sockets/channels compat layer (not done)
williamstein Jan 29, 2025
040f373
nats: work in progress implementing primus style messaging on top of …
williamstein Jan 29, 2025
b852342
nats primus -- implemented basics of sparks.
williamstein Jan 29, 2025
42318f9
Merge branch 'master' into nats
williamstein Jan 29, 2025
acb4a2e
nats: get terminal fully working with "primus over nats"
williamstein Jan 29, 2025
fd8077c
nats primus: add ping interval and implement auto destroy on server side
williamstein Jan 30, 2025
445d048
nats: primus -- going to give upon this approach
williamstein Jan 30, 2025
e053a9d
nats: enable by default new project api and terminal using nats
williamstein Jan 30, 2025
c74abd9
nats: creating typescript project RPC framework
williamstein Jan 30, 2025
077c2c4
nats: start newest project api as part of starting project and add te…
williamstein Jan 30, 2025
5a610b1
nats project api: add more system functions
williamstein Jan 30, 2025
1f701f5
nats project api: add configuration
williamstein Jan 30, 2025
c2c81b2
nats project api -- implemented basically everything but sync support…
williamstein Jan 30, 2025
41d4508
nats projects: cleaning up naming (via refactor) and supporting compu…
williamstein Jan 31, 2025
c30c16a
nats: converting frontend to user new project api (and also add suppo…
williamstein Jan 31, 2025
1c4dbdc
nats: implement for kv for tracking open-files
williamstein Jan 31, 2025
2b20b90
nats OpenFiles tracker -- more work on it
williamstein Jan 31, 2025
72c4d2e
nats sync: when client browser has document open, it periodically
williamstein Jan 31, 2025
47f026c
nats open files tracker -- working on it
williamstein Jan 31, 2025
5f696a7
nats synctable-kv -- work in progress
williamstein Jan 31, 2025
3f217b9
nats synctable: writing complicated code I do NOT like. This feels l…
williamstein Jan 31, 2025
f6cf4da
nats kv synctable -- more subtle coding
williamstein Jan 31, 2025
98dc26b
nats synctable -- make non-atomic kv synctable work consistently for …
williamstein Jan 31, 2025
6e75adc
nats: plug in new synctable-kv to syncdoc for syncstrings table
williamstein Jan 31, 2025
cf77d7c
nats sync: get saving to disk to work
williamstein Jan 31, 2025
db5011e
nats: incorporate open-files service into project so it automatically…
williamstein Feb 1, 2025
2936021
nats sync: backend syncdocs working with proper doctype
williamstein Feb 1, 2025
bc2d855
nats auth: implement function to remove project permissions
williamstein Feb 1, 2025
a18e29f
nats: add generic pub/sub with event emitter, which I'm now using to …
williamstein Feb 1, 2025
a72862d
nats cursors -- make it work :-)
williamstein Feb 2, 2025
538188a
Merge branch 'master' into nats
williamstein Feb 2, 2025
82ac7c0
enable nats-based synctable for database changefeeds; also make the i…
williamstein Feb 2, 2025
5ea6e0c
nats: integrate hub database service; refactor and use getAll more
williamstein Feb 2, 2025
b4567d3
nats: typescript fix and reminder
williamstein Feb 2, 2025
851c7a6
nats: improve docs and initial configuration
williamstein Feb 2, 2025
02b0af2
nats: tiny bit more docs
williamstein Feb 2, 2025
937f5b8
don't recomend nats env
williamstein Feb 2, 2025
9028029
nats database changefeeds -- rewrite how they work to address several…
williamstein Feb 2, 2025
8412f2d
nats database synctable: implement a major optimization
williamstein Feb 2, 2025
090ebfc
sync editing -- commit more frequently
williamstein Feb 2, 2025
6d17cb8
nats: eliminate use of hub websocket for changefeeds... but
williamstein Feb 2, 2025
6b43eb7
nats query client: fix return format so now crm works fine :-)
williamstein Feb 2, 2025
4653cc2
nats: work in progress refactoring touch, touch_project
williamstein Feb 2, 2025
3dd81a2
nats: eliminate old touch codepath -- use new api
williamstein Feb 3, 2025
e97c18b
user_tracking: switch to nats api; at admin setting so it is disabled…
williamstein Feb 3, 2025
092bfc5
remove web browser prometheus reporting
williamstein Feb 3, 2025
5e8856e
nats/api: only use new api for managing api keys... and
williamstein Feb 3, 2025
c12c036
delete ancient deprecated code for zendesk in the app
williamstein Feb 3, 2025
197fe9a
nats: rewrite streaming LLM output to use ephemeral nats jetstreams a…
williamstein Feb 3, 2025
5875d37
nats: implement a very cool key:value store wrapper, which we're goin…
williamstein Feb 4, 2025
c5af663
nats: framework for system config -- not used yet
williamstein Feb 4, 2025
f9237d3
nats hub: add authtoken rpc
williamstein Feb 4, 2025
bb106ff
database: rewrite central log save in typescript
williamstein Feb 4, 2025
acb2a1a
nats: switch admin user impersonate to new api
williamstein Feb 4, 2025
bb57170
nats hub -- rewrite user search
williamstein Feb 4, 2025
2df7477
nats: rewrite getNames to use new api
williamstein Feb 4, 2025
fa63cde
nats: user new api for getBalance
williamstein Feb 4, 2025
21f831d
Merge branch 'master' into nats
williamstein Feb 4, 2025
867f350
oops -- metrics-recorder is of course used for more than just browser…
williamstein Feb 4, 2025
76a6610
nats: new api for create project
williamstein Feb 4, 2025
8c04d87
nats: add new api support for read/write text file to project
williamstein Feb 4, 2025
c90e4e3
nats: improve the kv a little more
williamstein Feb 4, 2025
108f3fe
nats: improve kv store even more
williamstein Feb 4, 2025
6ff85e5
fix some typescript issue with kv
williamstein Feb 5, 2025
10390fa
nats: work in progress rewriting copy path between projects...
williamstein Feb 5, 2025
e0a4c00
nats: first attempt at simple browser api.
williamstein Feb 5, 2025
c46e0c3
nats: clean up how sign in cookies are set; also set a new account_id…
williamstein Feb 5, 2025
2ef3d16
nats: fix changefeeds (they were hanging due to a refactor)
williamstein Feb 5, 2025
fcf157c
nats: make my req/reply api services be registered NATS microservices…
williamstein Feb 6, 2025
c103fd8
nats: locking down the JWT permissions rules
williamstein Feb 6, 2025
6c8c6b9
nats: fix terminal streams permissions
williamstein Feb 6, 2025
743f46d
nats auth: get rid of redundant code for specifying rules
williamstein Feb 6, 2025
e17448c
account prefs save error crashed server so fix this and make error be…
williamstein Feb 6, 2025
3e8bb44
nats: unify and improve the default connection parameters
williamstein Feb 6, 2025
9770162
nats: trying a little "eventually consistent KV" POC
williamstein Feb 6, 2025
f4579bc
nats kv: work in progress
williamstein Feb 7, 2025
8041513
nats: more work on eventually consistent key value store
williamstein Feb 7, 2025
b28442e
nats distributed key value store -- rename and document
williamstein Feb 7, 2025
eb977e3
nats: adding a stream wrapper
williamstein Feb 7, 2025
c69423e
nats stream class: much, much better
williamstein Feb 8, 2025
d4deba6
nats: create dstream = distributed eventually consistent stream class
williamstein Feb 8, 2025
6ff903b
nats: add stream limits
williamstein Feb 8, 2025
98b6ac2
nats filtered stream: implement all the limits
williamstein Feb 8, 2025
3c461b9
nats streams: support start_seq
williamstein Feb 8, 2025
18b8433
nats streams: better cache
williamstein Feb 8, 2025
bae0e05
nats: easy use of account/project streams from backend
williamstein Feb 8, 2025
7c1793e
nats stream: ability to fill in old values
williamstein Feb 8, 2025
88bde9a
nats streams: s[n] notation; new public streams (hub can write; proje…
williamstein Feb 8, 2025
017067e
nats: user friendly account/project/public kv an dkv
williamstein Feb 8, 2025
58d7066
nats: make it so our streams/kv's can have *arbitrary* names, rather …
williamstein Feb 9, 2025
fa1aff2
nats kv: make it possible to use *arbitrary strings* for keys
williamstein Feb 9, 2025
34f1457
nats: switching to new stream for terminal -- work in progress that d…
williamstein Feb 9, 2025
1f2a475
fix a circular reference issue
williamstein Feb 9, 2025
e583350
nats: new streams were hanging on startup
williamstein Feb 9, 2025
f058779
nats terminal: limit history size (in bytes)
williamstein Feb 9, 2025
e76dfca
nats auth: no longer use -terminal stream
williamstein Feb 9, 2025
21636fd
nats: implements limits for kv
williamstein Feb 9, 2025
0991640
nats dkv: implement limits; also handling of rejected changes due to …
williamstein Feb 9, 2025
fa07410
nats dstream: add reject event support
williamstein Feb 9, 2025
df98481
nats: add better time support to kv and stream
williamstein Feb 9, 2025
0a7eb65
nats: rewrite open files tracker to use new dkv
williamstein Feb 9, 2025
9cd3c07
nats: do not throttle dkv and dstream unless there are errors (e.g., …
williamstein Feb 9, 2025
f363cd0
nats: switch to using new dstream for patches table :-)
williamstein Feb 9, 2025
c1d2f6c
nats: broken (!) work in progress switching database changefeeds to n…
williamstein Feb 9, 2025
c903fa1
nats changefeeds -- fix some bugs with rewrite; this makes sense fina…
williamstein Feb 10, 2025
0874950
nats: implemented new "dko" = distributed key:object store, where whe…
williamstein Feb 10, 2025
4339bb8
switch to using new synctable based on new dko.
williamstein Feb 10, 2025
08b7302
nats: fully switched everything to my new kv/stream implementations, …
williamstein Feb 10, 2025
ac0b8ff
nats: subtle issues with deleting from non-atomic distributed changef…
williamstein Feb 11, 2025
5e30be6
messages table: don't merge in messages, since then deleting doesn't …
williamstein Feb 11, 2025
d8f25dc
nats: greatly speedup reading initial kv out of nats
williamstein Feb 11, 2025
6115ccc
nats install: improve install process, document better, newest nats-s…
williamstein Feb 11, 2025
13e61f0
nats: start unit testing; even found a bug in creating a change handler.
williamstein Feb 11, 2025
664afdf
nats dkv testing -- work in progress unit testing
williamstein Feb 11, 2025
3e61607
nats dkv -- more unit tests
williamstein Feb 11, 2025
3e08025
nats: unit testing 3-way merge conflict implementation
williamstein Feb 11, 2025
2e1b556
nats kv -- more unit tests, especially involving 3-way merge
williamstein Feb 11, 2025
e124221
nats: fix some bugs revealed by testing and caused by testing
williamstein Feb 12, 2025
b553711
nats: fix major issue with hangs at scale (due to lack of auth)
williamstein Feb 12, 2025
00a3737
nats database synctable -- free synctables (avoid eventemitter leaks,…
williamstein Feb 12, 2025
01b5fc6
nats: solve the req/reply "inbox security" issue for users via inbox …
williamstein Feb 12, 2025
f4cdd2a
database user tracker: properly fix subtle bug that would cause issue…
williamstein Feb 12, 2025
195d54a
Merge branch 'master' into nats
williamstein Feb 12, 2025
29f1f5b
use test namespace for testing nats kv and streams.
williamstein Feb 12, 2025
26a7221
nats dstream: fix some bugs and create some unit tests
williamstein Feb 12, 2025
4994b84
nats dstream: add unit tests and fix bugs
williamstein Feb 13, 2025
e4c10ec
nats: adjust parallel param and make comment in unit tests about speed
williamstein Feb 13, 2025
825a16c
nats dkv: better testing null/undefined values (and fix bug testing r…
williamstein Feb 13, 2025
f3c53f6
nats: fix the @cocalc/sync test suite by not making *it* use nats
williamstein Feb 13, 2025
1e60bd4
fixing unit tests
williamstein Feb 13, 2025
d426771
delete the exec shell code api test
williamstein Feb 13, 2025
ae89578
admin impersonation: fix some bugs in my new implementation
williamstein Feb 13, 2025
c6961fc
nats open file data: improving it
williamstein Feb 13, 2025
9ee9323
nats sync: fix opening non-string first time
williamstein Feb 13, 2025
139bb21
nats: unit test open-files
williamstein Feb 13, 2025
a6ae9c4
nats sync objects: mostly improving caching and testing
williamstein Feb 13, 2025
db264ec
nats + trimetravel -- make timetravel close syncdoc it opens
williamstein Feb 14, 2025
6f30fa5
nats: create nice abstraction for services
williamstein Feb 14, 2025
b8bdad4
nats -- active jupyter
williamstein Feb 14, 2025
aae1da6
nats: ipywidgets support
williamstein Feb 14, 2025
bbed478
nats: wire up code formatter
williamstein Feb 14, 2025
e6b638f
nats: better call error messages
williamstein Feb 14, 2025
eb0d1b4
nats service: add a typed option
williamstein Feb 14, 2025
12957dd
switch jupyter to use new typed api
williamstein Feb 14, 2025
0e32a10
jupyter api: slightly better typing
williamstein Feb 14, 2025
8691b75
nats: auth -- fix service permissions
williamstein Feb 14, 2025
8159cae
nats sync: fix issue with changefeeds not working
williamstein Feb 15, 2025
a3bc1ea
nats: sage worksheets
williamstein Feb 15, 2025
9deb844
nats sync: expire ipywidgets
williamstein Feb 15, 2025
92ad19d
nats terminal: fixing some issues with initial load and sizing
williamstein Feb 15, 2025
d80b55d
nats: rewriting more terminal functionality
williamstein Feb 15, 2025
75801e3
nats: different approach to typed service RPC with terminal
williamstein Feb 15, 2025
5df9575
nats: yet another attempt at nice typed RPC api microservices
williamstein Feb 15, 2025
5ccf778
nats jupyter api: more typing
williamstein Feb 15, 2025
0e932d1
nats terminal: properly implementing browser side
williamstein Feb 16, 2025
f08bc33
terminal: mostly implement "kick"
williamstein Feb 16, 2025
98b24b9
nats services: incorporate stats/info/ping/waitFor
williamstein Feb 16, 2025
7b215d6
nats: improve terminal startup robustness
williamstein Feb 16, 2025
16b8e0e
nats terminal: implement 'kick'
williamstein Feb 16, 2025
c61fcb4
nats terminal: deleting old code, mostly
williamstein Feb 16, 2025
b636af3
nats: make initial load of stream much faster and always load it all
williamstein Feb 16, 2025
9124f53
dstream -- support optional typing
williamstein Feb 16, 2025
586dfc3
add typing support to DKO, DKV, KV, DStream, Stream
williamstein Feb 16, 2025
cdf0f1c
nats: work in progress rewriting listings
williamstein Feb 17, 2025
3a2c32b
nats: implementing new directory listings watcher
williamstein Feb 17, 2025
2e9c543
nats listings: packaged client
williamstein Feb 17, 2025
0338401
nats listings -- start integrating with frontend
williamstein Feb 17, 2025
f1dbea2
make 'cc.current()' better to aid in debugability of cocalc
williamstein Feb 17, 2025
b16a35c
nats: work in progress on revamping directory listings state
williamstein Feb 17, 2025
708fe11
open-files: dealing with deleted files
williamstein Feb 17, 2025
1b760e4
nats: add monitoring to kv store
williamstein Feb 18, 2025
eec42ba
nats kv: confirmed that my monitor works
williamstein Feb 18, 2025
ca7ea3c
nats-based delete file management: deal with some edge cases exposed …
williamstein Feb 18, 2025
4214fec
nats file deletion handling: work in progress
williamstein Feb 18, 2025
cd3a551
nats: handling deleted files
williamstein Feb 18, 2025
b7c2ca2
nats: starting project and initial listing -- improve
williamstein Feb 18, 2025
d1bb47e
nats compute servers: change frontend to use new nats based manager
williamstein Feb 19, 2025
2f539f0
nats compute servers -- make project open-files use the new manager i…
williamstein Feb 19, 2025
921b1aa
nats compute servers: improve file and terminal switching
williamstein Feb 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
299 changes: 299 additions & 0 deletions docs/nats/devlog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
# NATS Development and Integration Log

## [x] Goal: nats from nodejs

- start a nats server in cocalc\-docker
- connect from nats cli outside docker
- connect to it from the nodejs client over a websocket

```sh
nats-server -p 5004

nats context save --select --server nats://localhost:5004 nats

nats sub '>'
```

Millions of messages a second works \-\- and you can run like 5x of these at once without saturating nats\-server.

```js
import { connect, StringCodec } from "nats";
const nc = await connect({ port: 5004 });
console.log(`connected to ${nc.getServer()}`);
const sc = StringCodec();

const t0 = Date.now();
for (let i = 0; i < 1000000; i++) {
nc.publish("hello", sc.encode("world"));
}
await nc.drain();
console.log(Date.now() - t0);
```

That was connecting over TCP. Now can we connect via websocket?

## [x] Goal: Websocket from browser

First need to start a nats **websocket** server instead on port 5004:

[https://nats.io/blog/getting\-started\-nats\-ws/](https://nats.io/blog/getting-started-nats-ws/)

```sh
nats context save --select --server ws://localhost:5004 ws
~/nats/nats.js/lib$ nats context select ws
NATS Configuration Context "ws"

Server URLs: ws://localhost:5004
Path: /projects/3fa218e5-7196-4020-8b30-e2127847cc4f/.config/nats/context/ws.json

~/nats/nats.js/lib$ nats pub foo bar
21:24:53 Published 3 bytes to "foo"
~/nats/nats.js/lib$
```

##

- their no\-framework html example DOES work for me!
- [https://localhost:4043/projects/3fa218e5\-7196\-4020\-8b30\-e2127847cc4f/files/nats/nats.js/lib/ws.html](https://localhost:4043/projects/3fa218e5-7196-4020-8b30-e2127847cc4f/files/nats/nats.js/lib/ws.html)
- It takes about 1\-2 seconds to send **one million messages** from browser outside docker to what is running inside there!

## [x] Goal: actually do something useful

- nats server
- browser connects via websocket port 5004
- nodejs hub connects via tcp
- hub answers a ping or something else from the browser...

This worked perfectly with no difficulty. It's very fast and flexible and robust.

Reconnects work, etc.

## [x] Goal: proxying

- nats server with websocket listening on localhost:5004
- proxy it via node\-proxy in the hub to localhost:4043/nats
- as above

This totally worked!

Everything is working that I try?!

Maybe NATS totally kicks ass.

## [x] Goal: do something actually useful.

- authentication: is there a way to too who the user who made the websocket connection is?
- worry about this **later** \- obviously possible and not needed for a POC
- let's try to make `write_text_file_to_project` also be possible via nats.
- OK, made some of api/v2 usable. Obviously this is really minimal POC.

## [x] GOAL: do something involving the project

The most interesting use case for nats/jetsteam is timetravel collab editing, where this is all a VERY natural fit.

But for now, let's just do _something_ at all.

This worked - I did project exec with subject projects.{project_id}.api

## [x] Goal: Queue group for hub api

- change this to be a queue group and test by starting a few servers at once

## [x] Goal: Auth Strategy that is meaningful

Creating a creds file that encodes a JWT that says what you can publish and subscribe to, then authenticating with that works.

- make it so user with account_id can publish to hub.api.{account_id} makes it so we know the account_id automatically by virtue of what was published to. This works.

## [x] Goal: Solve Critical Auth Problems

Now need to solve two problems:

- [x] GOAL: set the creds for a browser client in a secure http cookie, so the browser can't directly access it

I finally figured this out after WASTING a lot of time with stupid AI misleading me and trying actively to get me to write very stupid insecure code as a lazy workaround. AI really is very, very dangerous... The trick was to read the docs repeatedly, increase logging a lot, and \-\- most imporantly \-\- read the relevant Go source code of NATS itself. The answer is to modify the JWT so that it explicitly has bearer set: `nsc edit user wstein --bearer`

This makes it so the server doesn't check the signature of the JWT against the _user_ . Putting exactly the JWT token string in the cookie then works because "bearer" literally tells the backend server not to do the signature check. I think this is secure and the right approach because the server checks that the JWT is valid using the account and operator signatures.

**WAIT!** Using signing keys [https://docs.nats.io/using\-nats/nats\-tools/nsc/signing_keys](https://docs.nats.io/using-nats/nats-tools/nsc/signing_keys) \(and https://youtu.be/KmGtnFxHnVA?si=0uvLMBTJ5TUpem4O \) is VASTLY superior. There's just one JWT issued to each user, and we make a server\-side\-only JWT for their account that has everything. The user never has to reconnect or change their JWT. We can adjust the subject on the fly to account for running projects \(or collaboration changes\) at any time server side. Also the size limits go away, so we don't have to compress project_id's \(probably\).

## Goal: Implement Auth Solution for Browsers

- [x] automate creation of creds for browser clients, i.e., what we just did with the nsc tool manually
-

---

This is my top priority goal for NOW!

What's the plan?

Need to figure out how to do all the nsc stuff from javascript, storing results in the database?

- Question: how do we manage creating signing keys and users from nodejs? Answer: clear from many sources that we must use the nsc CLI tool via subprocess calls. Seems fine to me.
- [x] When a user signs in, we check for their JWT in the database. If it is there, set the cookie. If not, create the signing key and JWT for them, save in database, and set the cookie.
- [x] update nats\-server resolver state after modifying signing cookie's subjects configuration.

```
nsc edit operator --account-jwt-server-url nats://localhost:4222
```

Now I can do `nsc push` and it just works.

[x] TODO: when signing out, need to delete the jwt cookie or dangerous private info leaks... and also new info not set properly.

- [x] similar creds for projects, I.e., access to a project means you can publish to `projects.{project_id}.>` Also, projects should have access to something under hub.

## [x] Goal: Auth for Projects

Using an env variable I got a basic useful thing up and running.

---

Some thoughts about project auth security:

- [ ] when collaborators on a project leave maybe we change JWT? Otherwise, in theory any user of a project can probably somehow get access to the project's JWT \(it's in memory at least\) and still act as the project. Changing JWT requires reconnect. This could be "for later", since even now we don't have this level of security!
- [ ] restarting project could change JWT. That's like the current project's secret token being changed.

## [ ] Goal: nats-server automation of creation and configuration of system account, operator, etc.

- This looks helpful: https://www.synadia.com/newsletter/nats-weekly-27/
- NOT DONE YET

## [x] Goal: Terminal! Something complicated involving the project which is NOT just request/response

- Implementing terminals goes beyond request/response.
- It could also leverage jetstream if we want for state (?).
- Multiple connected client

Project/compute server sends terminal output to

project.{project_id}.terminal.{sha1(path)}

Anyone who can read project gets to see this.

Browser sends terminal input to

project.{project_id}.{group}.{account_id}.terminal.{sha1(path)}

API calls:

- to start terminal
- to get history (move to jetstream?)

If I can get this to work, then collaborative editing and everything else is basically the same (just more details).

## [x] Goal: Terminal! #now

Make it so an actual terminal works, i.e., UI integration.

## [x] Goal: Terminal JetStream state

Use Jetstream to store messages from terminal, so user can reconnect without loss. !? This is very interesting...

First problem -- we used the system account SYS for all our users; however,
SYS can't use jetstreams, as explained here https://github.com/nats-io/nats-server/discussions/6033

Let's redo *everything* with a new account called "cocalc".

```sh
~/nats$ nsc create account --name=cocalc
[ OK ] generated and stored account key "AD4G6R62BDDQUSCJVLZNA7ES7R3A6DWXLYUWGZV74EJ2S6VBC7DQVM3I"
[ OK ] added account "cocalc"
~/nats$ nats context save admin --creds=/projects/3fa218e5-7196-4020-8b30-e2127847cc4f/.local/share/nats/nsc/keys/creds/MyOperator/cocalc/admin.creds
~/nats$ nsc edit account cocalc --js-enable 1
~/nats$ nsc push -a cocalc
```

```js
// making the stream for ALL terminal activity
await jsm.streams.add({ name: 'project-81e0c408-ac65-4114-bad5-5f4b6539bd0e-terminal', subjects: ['project.81e0c408-ac65-4114-bad5-5f4b6539bd0e.terminal.>'] });

// making a consumer for just one subject (e.g., one terminal frame)
z = await jsm.consumers.add('project-81e0c408-ac65-4114-bad5-5f4b6539bd0e-terminal',{name:'9149af7632942a94ea13877188153bd8bf2ace57',filter:['project.81e0c408-ac65-4114-bad5-5f4b6539bd0e.terminal.9149af7632942a94ea13877188153bd8bf2ace57']})
c = await js.consumers.get('project-81e0c408-ac65-4114-bad5-5f4b6539bd0e-terminal', '9149af7632942a94ea13877188153bd8bf2ace57')
for await (const m of await c.consume()) { console.log(cc.client.nats_client.jc.decode(m.data))}
```

NOTE!!! The above consumer is ephemeral -- it disappears if we don't grab it via c within a few seconds!!!! https://docs.nats.io/using-nats/developer/develop_jetstream/consumers

## [ ] Goal: Jetstream permissions

- [x] project should set up the stream for capturing terminal outputs.
- [x] delete old messages with a given subject. `nats stream purge project-81e0c408-ac65-4114-bad5-5f4b6539bd0e-terminal --seq=7000`
- there is a setting max\_msgs\_per\_subject on a stream, so **we just set that and are done!** Gees. It is too easy.
- [x] handle the other messages like resize
- [x] need to move those other messages to a different subject that isn't part of the stream!!
- [ ] permissions for jetstream usage and access
- [ ] use non\-json for the data....
- [ ] refactor code so basic parameters \(e.g., subject names, etc.\) are defined in one place that can be imported in both the frontend and backend.
- [ ] font size keyboard shortcut
- [ ] need a better algorithm for sizing since we don't know when a user disconnects!
- when one user proposes a size, all other clients get asked their current size and only those that respond matter. how to do this?

## [ ] Goal: Basic Collab Document Editing

Plan.

- [x] Use a kv store hosted on nats to trac syncstring objects as before. This means anybody can participate \(browser, compute server, project\) without any need to contact the database, hence eliminating all proxying!

[x] Next Goal \- collaborative file editing \-\- some sort of "proof of concept"! This requires implementing the "ordered patches list" but on jetstream. Similar to the nats SyncTable I wrote yesterday, except will use jetstream directly, since it is an event stream, after all.

- [x] synctable\-stream: change to one big stream for the whole project but **consume** a specific subject in that stream?

[ ] cursors \- an ephemeral table

---

- [ ] Subject For Particular File: `project.${project_id}.patches.${sha1(path)}`
- [ ] Stream: Records everything with this subject `project.${project_id}.patches`
- [ ] It would be very nice if we can use the server assigned timestamps.... but probably not
- [ ] For transitioning and de\-archiving, there must be a way to do this, since they have a backup/restore process

## [ ] Goal: PostgreSQL Changefeed Synctable

This is critical to solve. This sucks now. This is key to eliminating "hub\-websocket". This might be very easy. Here's the plan:

- [x] make a request/response listener that listens on hub.account.{account\_id} and hub.db.project.{project\_id} for a db query.
- [x] if changes is false, just responds with the result of the query.
- [ ] if changes is true, get kv store k named `account-{account_id}` or `project-{project_id}` \(which can be used by project or compute server\).
- let id be the sha1 hash of the query \(and options\)
- k.id.update is less than X seconds ago, do nothing... it's already being updated by another server.
- do the query to the database \(with changes true\)
- write the results into k under k.id.data.key = value.
- keep watching for changes so long as k.id.interest is at most n\*X seconds ago.
- Also set k.id.update to now.
- return id
- [ ] another message to `hub.db.{account_id}` which contains a list of id's.
- When get this one, update k.id.interest to now for each of the id's.

With the above algorithm, it should be very easy to reimplement the client side of SyncTable. Moreover, there are many advantages:

- For a fixed account\_id or project\-id, there's no extra work at all for 1 versus 100 of them. I.e., this is great for opening a bunch of distinct browser windows.
- If you refresh your browser, everything stays stable \-\- nothing changes at all and you instantly have your data. Same if the network drops and resumes.
- When implementing our new synctable, we can immediately start with the possibly stale data from the last time it was active, then update it to the correct data. Thus even if everything but NATS is done/unavailable, the experience would be much better. It's like "local first", but somehow "network mesh first". With a leaf node it would literally be local first.

---

This is working well!

TODO:

- [x] build full proof of concept SyncTable on top of my current implementation of synctablekvatomic, to _make sure it is sufficient_
- this worked and wasn't too difficult

THEN do the following to make it robust and scalable

- [ ] store in nats which servers are actively managing which synctables
- [ ] store in nats the client interest data, instead of storing it in memory in a server? i.e., instead of client making an api call, they could instead just update a kv and say "i am interested in this changefeed". This approach would make everything just keep working easily even as servers scale up/down/restart.

---

## [ ] Goal: Terminal and **compute server**

Another thing to do for compute servers:

- use jetstream and KV to agree on _who_ is running the terminal?

This is critical to see how easily we can support compute servers using nats + jetstream.

24 changes: 14 additions & 10 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# How to Build and Run CoCalc

Updated: **Jan 2023**
**Updated: Feb 2025**

CoCalc is a pretty large and complicated project, and it will only work with the current standard LTS release of node.js \( at least 16.8.x\) and a recent version of [pnpm](https://pnpm.io/).
CoCalc is a pretty large and complicated project, and it will only work with the current standard LTS release of node.js \( at least 18.17.1\) and a recent version of [pnpm](https://pnpm.io/). Also, you will need a LOT of RAM, a minimum of 16 GB. **It's very painful to do development with less than 32 GB of RAM.**

**Node.js and NPM Version Requirements:**

- You must be using Node version 16.8.x or newer. **CoCalc will definitely NOT work with any older version!** In a [CoCalc.com](http://CoCalc.com) project, you can put this in `~/.bashrc` to get a valid node version:
- You must be using Node version 18.17.1 or newer. **CoCalc will definitely NOT work with any older version!** In a [CoCalc.com](http://CoCalc.com) project, you can put this in `~/.bashrc` to get a valid node version:

```sh
. /cocalc/nvm/nvm.sh
Expand Down Expand Up @@ -56,22 +56,25 @@ To install required dependencies, run
hand, you prefer that development packages be installed globally, you can jump directly to the above `pip install`
command outside the context of a virtual environment.

## Initial Build
## Build and Start

Launch the install and build **for doing development:**
Launch the install and build **for doing development.**

If you export the PORT environment variable, that determines what port everything listens on. This determines subtle things about configuration, so do this once and for all in a consistent way.

**Note**: If you installed `pnpm` locally (instead of globally), simply run `npm run` in place of `pnpm` to execute
these commands via [NPM run scripts](https://docs.npmjs.com/cli/v10/using-npm/scripts).

```sh
~/cocalc/src$ pnpm make-dev
~/cocalc/src$ pnpm build-dev
```

This will do `pnpm install` for all packages, and also build the typescript/coffeescript, and anything else into a dist directory for each module. Once `pnpm make` finishes successfully, you can start using CoCalc by starting the database and the backend hub in two separate terminals.
This will do `pnpm install` for all packages, and also build the typescript/coffeescript, and anything else into a dist directory for each module. Once `pnpm build-dev` finishes successfully, you can start using CoCalc by starting the database, nats server and the backend hub in three terminals. \(Note that 'pnpm nats\-server' will download, install and configure NATS automatically.\) You can start the database, nats\-server and hub in any order.

```sh
~/cocalc/src$ pnpm database # in one terminal
~/cocalc/src$ pnpm hub # in another terminal
~/cocalc/src$ pnpm database # in one terminal
~/cocalc/src$ pnpm nats-server # in one terminal
~/cocalc/src$ pnpm hub # in another terminal
```

The hub will send minimal logging to stdout, and the rest to `data/logs/log`.
Expand All @@ -95,7 +98,7 @@ The main \(only?\) difference is that static and next webpack builds are created
If necessary, you can delete all the `node_modules` and `dist` directories in all packages and start over as follows:

```sh
~/cocalc/src$ pnpm clean && pnpm make-dev
~/cocalc/src$ pnpm clean && pnpm build-dev
```

## Doing Development
Expand Down Expand Up @@ -218,3 +221,4 @@ Regarding VS Code, the relevant settings can be found by searching for "autosave
There's some `@cocalc/` packages at [NPMJS.com](http://NPMJS.com). However, _**we're no longer using**_
_**them in any way**_, and don't plan to publish anything new unless there
is a compelling use case.

5 changes: 4 additions & 1 deletion src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
"version-check": "pip3 install typing_extensions mypy || pip3 install --break-system-packages typing_extensions mypy && ./workspaces.py version-check && mypy scripts/check_npm_packages.py",
"test-parallel": "unset DEBUG && pnpm run version-check && cd packages && pnpm run -r --parallel test",
"test": "unset DEBUG && pnpm run version-check && cd packages && pnpm run -r test",
"prettier-all": "cd packages/"
"prettier-all": "cd packages/",
"nats-server": "cd ${COCALC_ROOT:=$INIT_CWD}/packages/backend && node -e \"require('@cocalc/backend/nats/conf').main()\" && cd ${COCALC_ROOT:=$INIT_CWD}/data/nats && ./bin/nats-server -c server.conf",
"nats-server-verbose": "cd ${COCALC_ROOT:=$INIT_CWD}/packages/backend && node -e \"require('@cocalc/backend/nats/conf').main()\" && cd ${COCALC_ROOT:=$INIT_CWD}/data/nats && ./bin/nats-server -DV -c server.conf",
"nats-cli": "echo; echo '# Use CoCalc config of NATS (nats and nsc) via this subshell:'; echo; echo \"export XDG_DATA_HOME=${COCALC_ROOT:=$INIT_CWD}/data\"; echo \"export XDG_CONFIG_HOME=${COCALC_ROOT:=$INIT_CWD}/data\"; echo \"export PATH=${COCALC_ROOT:=$INIT_CWD}/data/nats/bin:\\$PATH\"; echo; echo; XDG_DATA_HOME=${COCALC_ROOT:=$INIT_CWD}/data XDG_CONFIG_HOME=${COCALC_ROOT:=$INIT_CWD}/data PATH=${COCALC_ROOT:=$INIT_CWD}/data/nats/bin:$PATH bash"
},
"repository": {
"type": "git",
Expand Down
Loading
Loading