Skip to content

Commit 77f1750

Browse files
committed
Update docs and fix polling for clients
1 parent 0ac07dd commit 77f1750

File tree

4 files changed

+49
-29
lines changed

4 files changed

+49
-29
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 0.14.1 (2020-07-30)
4+
5+
* Ensure clients can poll, by listening with (while) instead of (when)
6+
* Update documentation with examples of 'CLIENT' commands
7+
38
## 0.14.0 (2020-07-27)
49

510
* Fix bug where client IP is not saved in client list

README.md

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,21 @@ Background saving started
259259
./client.l --pass yourpass CONVERT
260260
OK 25E3B970
261261
OK
262+
263+
# Get the list of connected clients
264+
./client.l --pass yourpass CLIENT LIST
265+
OK 6FC82046
266+
id=2 pid=26377 name=6FC82046 addr=::1 fd=7
267+
id=1 pid=26370 name=783EABE1 addr=::1 fd=7
268+
269+
# Get the current client ID
270+
./client.l --pass yourpass CLIENT ID
271+
OK 105ECBFE
272+
273+
# Stop and kill a client connection
274+
./client.l --pass yourpass CLIENT KILL ID 1
275+
OK 32CA1C8A
276+
1
262277
```
263278

264279
# Notes and limitations
@@ -326,30 +341,30 @@ The idea is to have the **sibling** be the holder of all the **keys**. Every _"R
326341

327342
Similar to [Redis](https://redis.io/topics/persistence), this database implements "snapshotting" (full memory dump to disk) and "AOF" (append-only log file), however both features are tightly coupled, which makes for a much better experience.
328343

329-
* Persistence is disabled by default, but can be enabled with the `--persist N` parameter, where `N` is the number of seconds between each `BGSAVE` (background save to disk).
330-
* The database is stored in plaintext by default, but can be stored in binary with the `--binary` parameter. Binary format (PLIO) loads and saves _much_ quicker than plaintext, but it becomes difficult to debug a corrupt entry.
331-
* The AOF follows the _WAL_ approach, where each write command is first written to the AOF on disk, and then processed in the key/value memory store.
332-
* The AOF only stores log entries since the previous `SAVE` or `BGSAVE`, so it technically shouldn't grow too large or unmanageable.
333-
* The database snapshot on disk is the most complete and important data, and should be backed up regularly.
334-
* _fsync_ is not managed by the database, so the server admin must ensure AOF log writes are actually persisted to disk.
335-
* The AOF on-disk format is **always plaintext**, to allow easy debugging and repair of a corrupt entry.
336-
* The AOF is opened for writing when the server is started, and closed only when the server is stopped (similar to web server log files). This lowers overhead of appending to the log, but requires care to avoid altering it while the server is running.
337-
* The `SAVE` and `BGSAVE` commands can still be sent even if persistence is disabled. This will dump the in-memory data to disk as if persistence was enabled.
344+
* Persistence is disabled by default, but can be enabled with the `--persist N` parameter, where `N` is the number of seconds between each `BGSAVE` (background save to disk).
345+
* The database is stored in plaintext by default, but can be stored in binary with the `--binary` parameter. Binary format (PLIO) loads and saves _much_ quicker than plaintext, but it becomes difficult to debug a corrupt entry.
346+
* The AOF follows the _WAL_ approach, where each write command is first written to the AOF on disk, and then processed in the key/value memory store.
347+
* The AOF only stores log entries since the previous `SAVE` or `BGSAVE`, so it technically shouldn't grow too large or unmanageable.
348+
* The database snapshot on disk is the most complete and important data, and should be backed up regularly.
349+
* _fsync_ is not managed by the database, so the server admin must ensure AOF log writes are actually persisted to disk.
350+
* The AOF on-disk format is **always plaintext**, to allow easy debugging and repair of a corrupt entry.
351+
* The AOF is opened for writing when the server is started, and closed only when the server is stopped (similar to web server log files). This lowers overhead of appending to the log, but requires care to avoid altering it while the server is running.
352+
* The `SAVE` and `BGSAVE` commands can still be sent even if persistence is disabled. This will dump the in-memory data to disk as if persistence was enabled.
338353

339354
## How persistence is implemented
340355

341356
Here we'll assume persistence was previously enabled and data has already been written and saved to disk.
342357

343-
1. On server start, some memory is pre-allocated according to the DB's file size.
344-
2. The DB is then fully restored to memory
345-
3. If the AOF contains some entries, it is fully replayed to memory
346-
4. The DB is saved once more to disk and the AOF gets wiped
347-
5. A timer is started to perform periodic background DB saves
348-
6. The AOF is opened for writes, and every new client connection sends the command to the AOF
349-
7. When a `BGSAVE` (non-blocking) command is received, a temporay copy of the AOF is made, the current AOF is wiped, and a background process is forked to save the DB to disk
350-
8. When a `SAVE` (blocking) command is received, a the in-memory DB is saved to disk and the AOF is wiped.
351-
9. A backup of the DB file is always made before overwriting the current DB file.
352-
10. To help handle concurrency and persistence, temporary files are named `.kv.db.lock`, `.kv.db.tmp`, `.kv.aof.lock`, and `.kv.aof.tmp`. It's best not to modify or delete those files while the server is running. They can be safely removed while the server is stopped.
358+
1. On server start, some memory is pre-allocated according to the DB's file size.
359+
2. The DB is then fully restored to memory
360+
3. If the AOF contains some entries, it is fully replayed to memory
361+
4. The DB is saved once more to disk and the AOF gets wiped
362+
5. A timer is started to perform periodic background DB saves
363+
6. The AOF is opened for writes, and every new client connection sends the command to the AOF
364+
7. When a `BGSAVE` (non-blocking) command is received, a temporay copy of the AOF is made, the current AOF is wiped, and a background process is forked to save the DB to disk
365+
8. When a `SAVE` (blocking) command is received, the in-memory DB is saved to disk and the AOF is wiped.
366+
9. A backup of the DB file is always made before overwriting the current DB file.
367+
10. To help handle concurrency and persistence, temporary files are named `.kv.db.lock`, `.kv.db.tmp`, `.kv.aof.lock`, and `.kv.aof.tmp`. It's best not to modify or delete those files while the server is running. They can be safely removed while the server is stopped.
353368

354369
## AOF format
355370

@@ -362,11 +377,11 @@ Here are two separate entries in a typical AOF:
362377
("1596099059.683596840" 57240 ("RPUSH" "yourtestlist" ("seven" "eight" "nine")))
363378
```
364379

365-
Each line is a PicoLisp list with only 3 columns:
380+
Each line is a PicoLisp list with only 3 items:
366381

367-
* Column 1: `String` Unix timestamp with nanoseconds for when the entry was created
368-
* Column 2: `Integer` Non-cryptographically secure hash (CRC) of the command and its arguments
369-
* Column 3: `List` Command name, first argument, and subsequent arguments
382+
* Item 1: `String` Unix timestamp with nanoseconds for when the entry was created
383+
* Item 2: `Integer` Non-cryptographically secure hash (CRC) of the command and its arguments
384+
* Item 3: `List` Command name, first argument, and subsequent arguments
370385

371386
When replaying the AOF, the server will ensure the hash of command and arguments match, to guarantee the data is intact. Replaying an AOF can be slow, depending on the number of keys/values.
372387

@@ -392,10 +407,10 @@ Each line is a PicoLisp list with the key in the `(car)`, and values in the `(ca
392407

393408
## Differences from Redis
394409

395-
* Unlike _Redis_, persistence only allows specifying a time interval between each `BGSAVE`. Since the AOF is **always enabled**, it's not necessary to "save after N changes", so the config is much simpler.
396-
* Log rewriting is not something that "must be done", because chances are the AOF will never grow too large. Of course that depends on the number of changes occurring between each `BGSAVE`, but even then the AOF is wiped when a `BGSAVE` is initiated (and restored/rewritten if the DB happened to be locked).
397-
* The DB snapshot is used to reconstruct the dataset in memory, not the AOF. The AOF is only used to replay the commands since the last DB save, which is much faster and more efficient, particularly when using `--binary`.
398-
* There is no danger of _losing data_ when switching from `RDB` to `AOF`, because such a concept doesn't even exist.
410+
* Unlike _Redis_, persistence only allows specifying a time interval between each `BGSAVE`. Since the AOF is **always enabled**, it's not necessary to "save after N changes", so the config is much simpler.
411+
* Log rewriting is not something that "must be done", because chances are the AOF will never grow too large. Of course that depends on the number of changes occurring between each `BGSAVE`, but even then the AOF is wiped when a `BGSAVE` is initiated (and restored/rewritten if the DB happened to be locked).
412+
* The DB snapshot is used to reconstruct the dataset in memory, not the AOF. The AOF is only used to replay the commands since the last DB save, which is much faster and more efficient, particularly when using `--binary`.
413+
* There is no danger of _losing data_ when switching from `RDB` to `AOF`, because such a concept doesn't even exist.
399414

400415
# Testing
401416

child.l

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# Receive a message from the client over the TCP socket
1919
[de kv-listen-sock ()
2020
(in *Sock
21-
(when (rd)
21+
(while (rd)
2222
(let Msg @
2323
(kv-output "[msg] from client: (pid: " *Pid ") " *Adr " " (sym Msg))
2424
(kv-out-sibling "message" Msg)

module.l

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[de APP_INFO
22
("name" "picolisp-kv")
3-
("version" "0.13.0")
3+
("version" "0.14.1")
44
("summary" "Redis-inspired in-memory key/value store written in PicoLisp")
55
("source" "https://github.com/aw/picolisp-kv")
66
("author" "Alexander Williams")

0 commit comments

Comments
 (0)