13
238
Fork
You've already forked app
18

Periodic crash due to session garbage collection code #160

Closed
opened 2024年03月11日 17:30:15 +01:00 by aral · 2 comments
Owner
Copy link
🙀 Uncaught exception TypeError: e._db.sessions[n].hasExpired is not a function
 at file:///var/home/aral/.local/share/small-tech.org/kitten/app/kitten-bundle.js:434:9245
 at Array.forEach (<anonymous>)
 at Timeout._onTimeout (file:///var/home/aral/.local/share/small-tech.org/kitten/app/kitten-bundle.js:434:9215)
 at listOnTimeout (node:internal/timers:573:17)
 at process.processTimers (node:internal/timers:514:7) uncaughtException
``` 🙀 Uncaught exception TypeError: e._db.sessions[n].hasExpired is not a function at file:///var/home/aral/.local/share/small-tech.org/kitten/app/kitten-bundle.js:434:9245 at Array.forEach (<anonymous>) at Timeout._onTimeout (file:///var/home/aral/.local/share/small-tech.org/kitten/app/kitten-bundle.js:434:9215) at listOnTimeout (node:internal/timers:573:17) at process.processTimers (node:internal/timers:514:7) uncaughtException ```
Author
Owner
Copy link
🙀 Uncaught exception TypeError: kitten2._db.sessions[sessionId].hasExpired is not a function
 at file:///var/home/aral/.local/share/small-tech.org/kitten/app/kitten-bundle.js:206391:45
 at Array.forEach (<anonymous>)
 at Timeout.garbageCollectSessions [as _onTimeout] (file:///var/home/aral/.local/share/small-tech.org/kitten/app/kitten-bundle.js:206390:21)
 at listOnTimeout (node:internal/timers:573:17)
 at process.processTimers (node:internal/timers:514:7) uncaughtException
``` 🙀 Uncaught exception TypeError: kitten2._db.sessions[sessionId].hasExpired is not a function at file:///var/home/aral/.local/share/small-tech.org/kitten/app/kitten-bundle.js:206391:45 at Array.forEach (<anonymous>) at Timeout.garbageCollectSessions [as _onTimeout] (file:///var/home/aral/.local/share/small-tech.org/kitten/app/kitten-bundle.js:206390:21) at listOnTimeout (node:internal/timers:573:17) at process.processTimers (node:internal/timers:514:7) uncaughtException ```
Author
Owner
Copy link

Found the cause of this and it was non-trivial. I was encountering it while testing Domain and here’s why it was happening:

I started running this instance of Domain with a non-minified Kitten release. Among other things, this saved instances of the Session class in _db ­– the internal JSDB database. (JSDB supports persistence of custom data types.)

Then, I experimented with several builds of Kitten where Kitten was minified. While this was great in reducing the size of the bundle from over 8mb to under 5mb, it resulted in the names of identifiers (including classes) to be changed. So, for example, the Session might have been replaced with x1. The first time the database was loaded in with the minified build of Kitten, it could not find the x1 class in memory and so a plain object was created and plain objects, instead of Session instances were subsequently persisted.

As the session cleanup code expects to work with Session instances, it would try to access the hasExpired method, only for it to fail, as seen above.

This has now been fixed in 1af2eed897 where the Kitten bundle is now only built using esbuild’s --minify-whitespace and --minify-syntax flags (so without --minify-identifiers) and with --keep-names so that even if a class name should change due to the bundling, the name property of the class will still be set correctly (and this is what JSDB uses when persisting the entity to its append-only JavaScript log).

(Note that even without --minify-identifiers and with --keep-names, the bundle size currently stands at ~5.9mb, which is not bad at all.)

I’ve also opened a separate issue in JSDB to document this behaviour with a note that minification of identifiers should be avoided in projects that use JSDB.

If your app if affected

If you used any of the minified Kitten builds, you will have to manually clean-up Kitten’s internal database for your app.

To check

From your app’s directory, run:

kitten _db tail sessions --all

If you see entries in the following form, you’re find and don’t need to do anything:

export const _ = {}
 _['ezgJlDegjdeQUrie4btAqcqN'] = Object.create(typeof Session === 'function' ? Session.prototype : {}, Object.getOwnPropertyDescriptors({ 'createdAt': 1713546935651, 'authenticated': false, 'id': `ezgJlDegjdeQUrie4btAqcqN` }));
...

If, however, you see plain objects there instead, e.g.,

export const _ = {}
 _['ezgJlDegjdeQUrie4btAqcqN'] = { 'createdAt': 1713546935651, 'authenticated': false, 'id': `ezgJlDegjdeQUrie4btAqcqN` };
...

Then you need to nuke the sessions table:

kitten _db delete session

Note that the uploads table will likely also be affected so you might have to remove that also. Or, if you want to maintain your uploads, open the uploads table (remember it’s just a JavaScript file) in your editor of choice and surround the plain objects there with:

Object.create(typeof Upload === 'function' ? Upload.prototype : {}, Object.getOwnPropertyDescriptors({ ... }));
Found the cause of this and it was non-trivial. I was encountering it while testing Domain and here’s why it was happening: I started running this instance of Domain with a non-minified Kitten release. Among other things, this saved instances of the `Session` class in `_db` ­– the internal [JSDB](https://codeberg.org/small-tech/jsdb) database. (JSDB supports [persistence of custom data types](https://codeberg.org/small-tech/jsdb#custom-data-types).) Then, I experimented with several builds of Kitten where Kitten was minified. While this was great in reducing the size of the bundle from over 8mb to under 5mb, it resulted in the names of identifiers (including classes) to be changed. So, for example, the `Session` might have been replaced with `x1`. The first time the database was loaded in with the minified build of Kitten, it could not find the `x1` class in memory and so a plain object was created and plain objects, instead of `Session` instances were subsequently persisted. As the session cleanup code expects to work with `Session` instances, it would try to access the `hasExpired` method, only for it to fail, as seen above. This has now been fixed in https://codeberg.org/kitten/app/commit/1af2eed897d82f9978f46ff6a8fd47317071151e where the Kitten bundle is now only built using esbuild’s `--minify-whitespace` and `--minify-syntax` flags (so _without_ `--minify-identifiers`) and with `--keep-names` so that even if a class name should change due to the bundling, the `name` property of the class will still be set correctly (and this is what JSDB uses when persisting the entity to its append-only JavaScript log). (Note that even without `--minify-identifiers` and with `--keep-names`, the bundle size currently stands at ~5.9mb, which is not bad at all.) I’ve also opened [a separate issue in JSDB to document this behaviour](https://codeberg.org/small-tech/jsdb/issues/11) with a note that minification of identifiers should be avoided in projects that use JSDB. ## If your app if affected __If you used any of the minified Kitten builds__, you will have to manually clean-up Kitten’s internal database for your app. ### To check From your app’s directory, run: ```shell kitten _db tail sessions --all ``` If you see entries in the following form, you’re find and don’t need to do anything: ```js export const _ = {} _['ezgJlDegjdeQUrie4btAqcqN'] = Object.create(typeof Session === 'function' ? Session.prototype : {}, Object.getOwnPropertyDescriptors({ 'createdAt': 1713546935651, 'authenticated': false, 'id': `ezgJlDegjdeQUrie4btAqcqN` })); ... ``` If, however, you see plain objects there instead, e.g., ```js export const _ = {} _['ezgJlDegjdeQUrie4btAqcqN'] = { 'createdAt': 1713546935651, 'authenticated': false, 'id': `ezgJlDegjdeQUrie4btAqcqN` }; ... ``` Then you need to nuke the `sessions` table: ```shell kitten _db delete session ``` Note that the `uploads` table will likely also be affected so you might have to remove that also. Or, if you want to maintain your uploads, open the uploads table (remember it’s just a JavaScript file) in your editor of choice and surround the plain objects there with: ```js Object.create(typeof Upload === 'function' ? Upload.prototype : {}, Object.getOwnPropertyDescriptors({ ... })); ```
Sign in to join this conversation.
No Branch/Tag specified
main
full-typescript
stateful-components-api-breaking-change
ip-address-support
improved-markdown-pages
markdown-consistency
proper-markdown-implementation-take-2
proper-markdown-implementation
fix-markdown-links
improved-component-model
middleware-refactor
implicit-event-handlers
event-scopes
regression-tests
access-stats
stats
connected-components
streaming-html-kitten-chat-examples
data-encapsulation
domain-migrations
better-slash-forwarding-in-urls
manual-app-updates
logs
kitten-scoped-database
only-inform-small-web-host-of-status-updates-if-being-deployed-by-it
only-ping-domain-on-first-deploy
markdown-pages
node-22
id-command
settings-refactor
show-uploads-in-settings
backup-and-restore
database-view-in-settings
prewarmed-servers
htmx-2
html-and-css-fragments
without-source-maps
only-use-kitten-process-manager-for-development-servers
parameter-objects
page-socket-routes
versioning-and-package-json-changes
evergreen-web
auto-updates
build-web-into-dist
two-databases-are-better-than-one
kitten-namespace
npm-ci
use-my-htmx-fork
errors-not-exits-wip
standardisation
strong-typing-and-tests
kitten-tag
page-tag
db-table-delete
npm-install-and-validation-issues-on-html
busboy-express
readline-under-cluster
development-libraries
slots-and-classes
named-slots
credits
dot-js
markdown-fix
safer-fields
validation
wrapping-the-renderer
xhtm
end-to-end-encrypted-chat-example
chokidar-to-watcher-migration
alpinejs
uri-cleanup
web-settings
cryptography
settings-app
development-mode
post
No results found.
Labels
Clear labels
documentation
Anything related to documentation
error messages
Issues related to Kitten’s error message handling
examples
Related to apps in the examples folder
housekeeping
Improves code quality by refactoring redundancy, removing old code, etc.
low priority
A non-essential nice-to-have
needs design
Not a simple fix but something that requires architectural work
parser
Issues regard Kitten HTML parser (inc. Markdown)
tests
Related to tests (unit, end-to-end, etc.) in some way
usability
Anything that affects usability
accessibility
Accessibility-related issues
API
Issues related to Kitten’s public interface (for authors)
bug
Something is not working
CLI
Command-line interface related issues (Kitten commands)
contribution welcome
Contributions are very welcome, get started here
crash
A bug that crashes the server
deployment
Related to the deployment of Kitten apps/sites
duplicate
This issue or pull request already exists
enhancement
New feature
feature branch
Relates to a feature being developed in a separate branch (not main)
good first issue
Interested in contributing? Get started here.
help wanted
Need some help
installer
Issues related to the installation script
invalid
Something is wrong
is this still an issue?
Issues that need to be reproduced to confirm they haven’t already been fixed or made redundant
linux
Linux-specific issue
localisation
Localisation and internationalisation-related issues
macOS
macOS-specific issue
question
More information is needed
security
Security related issues
suggestion
upstream
Related to an upstream repository, already reported there
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kitten/app#160
Reference in a new issue
kitten/app
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?