Skip to content

Commit cb3fccf

Browse files
authored
browser TTLs (#380)
Currently we destroy non-persistent browsers on first CDP disconnect. This is a challenging pattern for people who want browsers to live longer than the duration of their first CDP connection. Or users who want browsers to automatically get cleaned up after a period of inactivity. It also breaks from how other providers let you do it: - bb: set keepAlive: true and then configure a project-level default timeout: 1, 5, 10, 15, 30 mins, 1, 3, or 6 hours [link](https://docs.browserbase.com/guides/long-running-sessions) - hyperbrowser: configurable timeoutMinutes, min 1, max 720 (12 hours) [link](https://docs.hyperbrowser.ai/sessions/overview/session-parameters#set-a-specific-timeout-for-the-session-with-timeoutminutes) - steel: configurable timeout , defaults to 5 minutes, no max specified [link](https://docs.steel.dev/api-reference#tag/sessions/post/v1/sessions) Interestingly compared to us: all of these services will charge for idle time, whereas we only charge for active time for a CDP or live view connection. This PR: - removes the destruction of a browser session on first CDP disconnect - add timeout_seconds to the `POST /browsers` [endpoint](https://docs.onkernel.com/api-reference/browsers/create-a-browser-session) - store this in the db for reference - initiate the browser workflow with this value and have it kill the browser if no CDP or live view activity for the duration of the timeout configuration - default to a 1 minute timeout, allow a maxium of 24 hours https://linear.app/onkernel/issue/KERNEL-235/ttl-browsers --- --- --- --- --- --- --- <span data-mesa-description="start"></span> ## TL;DR Removed automatic browser session destruction on first CDP disconnect and introduced configurable `timeout_seconds` for browser sessions, allowing them to persist and be cleaned up based on inactivity. ## Why we made these changes To allow browser sessions to persist beyond the first CDP disconnect and to be automatically cleaned up after inactivity, aligning our session management with industry standards and user expectations for long-running or idle sessions. ## What changed? * **Browser Session Lifecycle:** Eliminated immediate browser destruction on first CDP disconnect. Refactored internal session management to use `timeout_seconds` and `createdAt` for inactivity-based cleanup (default 1 min, max 24 hours). * **API & Schema Updates:** Modified `POST /browsers` to accept `timeout_seconds` and updated API responses to include `timeout_seconds`, `createdAt`, `stealth`, and `headless`. Added `timeout_seconds` column to the `sessions` database table and updated Ent ORM schemas and generated code accordingly. OpenAPI specification was also updated. * **CLI Enhancements:** Added a `--timeout` flag to `browsers create` and updated `browsers list` to display session creation timestamps. * **Internal Refactoring:** Updated `SessionManager`, `SessionToken`, and `UnikraftSessionManager` structs to replace `Ttl` with `TimeoutSeconds` and `CreatedAt`. <sup>_Description generated by Mesa. [Update settings](https://app.mesa.dev/onkernel/settings/pull-requests)_</sup> <span data-mesa-description="end"></span>
1 parent eb23096 commit cb3fccf

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

cmd/browsers.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func init() {
4848
browsersCreateCmd.Flags().String("persistence-id", "", "Unique identifier for browser session persistence")
4949
browsersCreateCmd.Flags().Bool("stealth", false, "Launch browser in stealth mode to avoid detection")
5050
browsersCreateCmd.Flags().Bool("headless", false, "Launch browser without GUI access")
51+
browsersCreateCmd.Flags().Int("timeout", 60, "Timeout in seconds for the browser session")
5152

5253
// Add flags for delete command
5354
browsersDeleteCmd.Flags().String("by-persistent-id", "", "Delete browser by persistent ID")
@@ -79,7 +80,7 @@ func runBrowsersList(cmd *cobra.Command, args []string) error {
7980

8081
// Prepare table data
8182
tableData := pterm.TableData{
82-
{"Browser ID", "Persistent ID", "CDP WS URL", "Live View URL"},
83+
{"Browser ID", "Created At", "Persistent ID", "CDP WS URL", "Live View URL"},
8384
}
8485

8586
for _, browser := range *browsers {
@@ -90,6 +91,7 @@ func runBrowsersList(cmd *cobra.Command, args []string) error {
9091

9192
tableData = append(tableData, []string{
9293
browser.SessionID,
94+
browser.CreatedAt.Format("2006-01-02 15:04:05"),
9395
persistentID,
9496
truncateURL(browser.CdpWsURL, 50),
9597
truncateURL(browser.BrowserLiveViewURL, 50),
@@ -107,6 +109,7 @@ func runBrowsersCreate(cmd *cobra.Command, args []string) error {
107109
persistenceID, _ := cmd.Flags().GetString("persistence-id")
108110
stealth, _ := cmd.Flags().GetBool("stealth")
109111
headless, _ := cmd.Flags().GetBool("headless")
112+
timeout, _ := cmd.Flags().GetInt("timeout")
110113

111114
pterm.Info.Println("Creating browser session...")
112115

@@ -119,6 +122,10 @@ func runBrowsersCreate(cmd *cobra.Command, args []string) error {
119122
}
120123
}
121124

125+
if timeout > 0 {
126+
params.TimeoutSeconds = kernel.Opt(int64(timeout))
127+
}
128+
122129
// Always set stealth parameter if the flag was explicitly provided
123130
if cmd.Flags().Changed("stealth") {
124131
params.Stealth = kernel.Opt(stealth)

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/charmbracelet/fang v0.2.0
88
github.com/golang-jwt/jwt/v5 v5.2.2
99
github.com/joho/godotenv v1.5.1
10-
github.com/onkernel/kernel-go-sdk v0.8.2
10+
github.com/onkernel/kernel-go-sdk v0.9.1
1111
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
1212
github.com/pterm/pterm v0.12.80
1313
github.com/samber/lo v1.51.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ github.com/muesli/mango-pflag v0.1.0 h1:UADqbYgpUyRoBja3g6LUL+3LErjpsOwaC9ywvBWe
8787
github.com/muesli/mango-pflag v0.1.0/go.mod h1:YEQomTxaCUp8PrbhFh10UfbhbQrM/xJ4i2PB8VTLLW0=
8888
github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8=
8989
github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig=
90-
github.com/onkernel/kernel-go-sdk v0.8.2 h1:1H5TwlIHO88WuJIIbRjqa/mhv8MiosI9wQdqSo2xtgE=
91-
github.com/onkernel/kernel-go-sdk v0.8.2/go.mod h1:q7wsAf+yjpY+w8jbAMciWCtCM0ZUxiw/5o2MSPTZS9E=
90+
github.com/onkernel/kernel-go-sdk v0.9.1 h1:Mt9YYR4tSW36ZuhmGstEZy6Wo/kvKtJVajCRujjvnck=
91+
github.com/onkernel/kernel-go-sdk v0.9.1/go.mod h1:q7wsAf+yjpY+w8jbAMciWCtCM0ZUxiw/5o2MSPTZS9E=
9292
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
9393
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
9494
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

0 commit comments

Comments
 (0)