v3.5.1
This release fixes several issues with the Modal-hosted deploy. It moves media serving and the
database off the volume's slow network layer so hosted video plays smoothly,
makes shutdown and spot preemption exit cleanly, completes the PWA install
behind the host login on iOS, and stops the installed app from re-prompting for
the password. It also fixes a previously uncaught clip-recording hang on iOS.
It has no breaking changes
Fixed
-
Launcher→ Besides an overall poor application performance when hosting onModal,
video playback stalled and clip recording failed. TheModalhost served media and ran
the database directly off the persistent volume'sFUSElayer, whose per-request random
reads take seconds, so every seek re-buffered and the browser recorder
(which captures live playback) had no continuous stream to record.
The host now reads and writes user data on the container's local disk and mirrors changes
to the volume in the background, keeping media and database I/O off the slow layer while
Modalstill persists the data -
Launcher→ TheModalhost could overrunModal's shutdown grace and be
force-killed (loggingRunner has been shutting down for too long) when a stop
or a spot preemption stranded an in-flight volume read on a background thread. A
watchdog (a daemon thread started at shutdown that terminates the process if it doesn't
exit in less than 10 seconds) now exits the container cleanly within the grace window,
so a stop or preemption releases promptly -
Launcher→ TheModalhost wrote its request log to the persistent volume
on every request, growing it unbounded and adding a volume write to the hot
path. It now logs to standard output, whichModalcaptures, so nothing is
written to the volume.Modalpersists logs natively through theStopped Apps
interface, so writing to a log file would be redundant and decrease performance -
Frontend→ The installedPWAicon did not render oniOSand the app was
not installable behind the host login.iOSfetches the manifest, its icons, and
theapple-touch-iconas install subresources without the login, so behind
HTTP Basic Auththey returned401. The host now serves exactly those public
install files without auth, while the shell, the hashed assets, and the API stay
gated -
Frontend→ An installediOSPWAre-prompted for the host password on
every reopen, sinceiOSdrops theBasic Authcredential cache when the app is
suspended. A passed login now sets a persistent,HttpOnlycookie that the host
accepts in place of the credentials, so a reopened app authenticates silently
(rotating the password invalidates it) -
Frontend→ Saving a clip oniOScould hang onRecordingfrom a fresh
player. The recorder's audio pipeline needs itsAudioContextresumed inside a
user gesture, but fetching the word explanation first spent it, leaving the audio
track dead. The save now resumes the context on the tap, and the recorder can no
longer hang indefinitely -
Server→GET /api/jobsreturned400for a poll that arrived without an
X-Profile-IDheader (a service-worker replay the app cannot attach the header
to). It now returns an empty list, so the errors stop