Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,25 @@ order; the entry is the editorial text of the version's GitHub Release. The 1.7
maintenance line continues in `CHANGELOG.md` on the `release/1.7` branch. This
project follows semantic versioning.

## [2.3.2]

Closes the state_history socket on the way out of a crash, and stops a one-way database flag from putting a far-behind reader into head mode.

### Upgrading

- Image `ghcr.io/atomicassets/atomicassets-api:2.3.2`. The `2.3` and `latest` tags move to it.
- The migration set is unchanged from 2.0.0, so the filler performs no database work on boot.
- A reader starts in catchup mode on every start and promotes itself to head mode on the first block that is either reversible or within twice `db_group_blocks` of the head. Every block at the chain head is reversible, so a reader genuinely at head reaches head mode on its first block, ahead of that block's commit and of its notifications. `contract_readers.live` is still written and `reconcile` still refuses a reader whose flag is set and whose row is fresh, so only the reader's processing state stopped deriving from it.

### Bug fixes

- The filler abandoned its `state_history` websocket instead of closing it when it left through `process.exit(1)`, which is the path an unhandled rejection, an uncaught exception, and both watchdog timers take. Both watchdog paths now take the graceful stop, whose close frame goes out during the pause they already had, and the crash handlers send the frame and exit on a short fixed timer. (#198)
- A reader that had once reached head started in head mode however far behind it restarted, because `contract_readers.live` goes true on that first arrival and nothing ever writes it back. The in-process promotion could not correct it, since it only fires while the state is still catchup, and the first commit rewrote the flag. Head mode costs a checkpoint write on every commit, and before 2.2.1 it published a whole backlog of trace and delta notifications from inside the commit path. (#199)

### Other changes

- `README.md` records what the filler's progress line means, so a slow catch-up can be told apart from a starved `state_history` feed without guesswork: what `DS`, `SH` and `W/s` measure, that the queue depths only discriminate while the in-flight window is larger than one, and what the throughput keys in `readers.config.json` do against the values a mainnet deployment runs. (#197)

## [2.3.1]

Re-reads the row a socket notification names until the replica the API queries has replayed the block that wrote it.
Expand Down
27 changes: 11 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -454,22 +454,17 @@ The estimate is not itself a fault signal. It models the chain producing two
blocks per second while you sync, so an average below that prints
`(Syncs never)` and an average barely above it prints an enormous hour count.

With `DS` and `SH` both high and `W/s` low, check whether the reader is stuck in
head mode. `contract_readers.live` is set when the reader first reaches head and
nothing sets it back, and the filler reads it at startup to choose head mode or
catch-up mode, without consulting the distance to head. A reader that once
reached head therefore starts in head mode however far behind it is. Before
2.2.1, head mode published every trace and delta to Redis inside the commit path,
a direct throughput cost on a backlog. Stop the filler, then:

```sql
SELECT name, block_num, live FROM contract_readers;
UPDATE contract_readers SET live = false WHERE name = '<reader>';
```

Start it again. It promotes itself back to head mode once it is genuinely near
head. Do this with the filler stopped, or the next commit rewrites the flag. Do
not change `block_num`: the checkpoint is correct and only the flag is wrong.
With `DS` and `SH` both high and `W/s` low, the filler is waiting on something
other than the database. Redis is the first place to look, because head mode
publishes notifications from inside the commit path, and deserialization is the
second: it runs on the reader's own thread for contract traces and rows, so it
shows as one thread pinned while the deserializer workers idle.

A reader from before 2.3.2 could also be stuck in head mode while far behind,
because it derived that state from `contract_readers.live`, which is set on the
first arrival at head and never written back. From 2.3.2 a reader always starts
in catch-up mode and promotes itself on the first block that is either reversible
or within twice `db_group_blocks` of the head, so no flag needs clearing.

With `DS` and `SH` both high and `W/s` high, the database write path is the
limit. Raise `db_group_blocks` and `max_wal_size` together. See
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "atomicassets-api",
"version": "2.3.1",
"version": "2.3.2",
"description": "AtomicAssets API: indexer and HTTP API for AtomicAssets, AtomicMarket, AtomicTools, and related contracts on Antelope (EOSIO) chains.",
"license": "MIT",
"author": "FACINGS INC.",
Expand Down