Go client
A Go client with the same behaviour as the Node client. It uses only the standard library and needs Go 1.22 or newer.
go get github.com/degoke/browserbay/clients/goQuick start
Section titled “Quick start”import browserbay "github.com/degoke/browserbay/clients/go"
box, err := browserbay.New(browserbay.Options{ URL: "https://browsers.example.com", APIKey: os.Getenv("BROWSERBAY_API_KEY"),})if err != nil { log.Fatal(err)}
slot, err := box.Acquire(ctx, browserbay.AcquireOptions{ RunID: "task-42", MaxLifetime: 30 * time.Minute,})if errors.Is(err, browserbay.ErrNoCapacity) { log.Fatal("every browser is busy, try again later")} else if err != nil { log.Fatal(err)}defer slot.Release(ctx) // idempotent
fmt.Println(slot.CDPURL, slot.Headers())Drive the browser
Section titled “Drive the browser”Give the slot’s address and headers to any DevTools client. With playwright-go:
browser, err := pw.Chromium.ConnectOverCDP(slot.CDPURL, playwright.BrowserTypeConnectOverCDPOptions{ Headers: map[string]string{browserbay.TokenHeader: slot.Token},})page, err := browser.Contexts()[0].NewPage() // the slot's own contextWith a raw WebSocket library such as gorilla/websocket, slot.Headers() returns an http.Header:
conn, _, err := websocket.DefaultDialer.DialContext(ctx, slot.CDPURL, slot.Headers())The live view guide shows what to send over such a connection.
The client
Section titled “The client”| Call | Does |
|---|---|
box.Acquire(ctx, opts) | Takes a browser. ErrNoCapacity when the box stays full for the whole Wait (default 30 s). |
box.Slot(stored) | A slot from what you saved earlier. Makes no request. |
box.Release(ctx, slotID) | Releases a slot you only know the id of. ReleaseAt(ctx, boxURL, slotID) for one on another box. |
box.List(ctx) | Slots (this namespace’s, if you set one), with their run ids. |
box.Nodes(ctx) | Nodes and their load. |
box.Reap(ctx, opts) | Releases slots whose run IsLive says is gone. Returns how many. |
slot.IsAlive(ctx) | Never fails. A box that cannot be asked counts as “not alive”. |
slot.Release(ctx) | Closes the browser. Idempotent. |
json.Marshal(slot) | What to save to come back later. It holds the slot token: store it like a secret. |
Options also takes Namespace, AllowOtherBoxes (a list of addresses a stored slot may name), AllowAnyBox, HTTPClient, Logger, Now and RetryDelay.
Things that differ from the Node client
Section titled “Things that differ from the Node client”- Zero means the default. To ask for the opposite use
browserbay.NoWait(do not wait for a free slot),browserbay.NoGrace(reap slots of any age) andbrowserbay.NoRetryDelay. - Every call takes a
context.Context. Cancel it to stop waiting. - Redirects. The default HTTP client refuses redirects to another host, because Go forwards custom headers such as the slot token on them. A client you supply is used as it is.
- Errors.
errors.Is(err, browserbay.ErrNoCapacity)for a full box,ErrQuotaExceededwhen the API key’s quota is used up (answered at once, without waiting),ErrForbiddenwhen the key is confined to another namespace (make the client with the matchingNamespace),ErrInvalidArgumentfor options refused before anything is sent,ErrUntrustedBoxfor a stored slot naming a box you have not allowed, anderrors.As(err, &apiErr)withvar apiErr *browserbay.Errorfor the HTTP status of anything else.
A saved slot is the same JSON as the Node and Python clients write, so any of the three can revive the others’ slots. See Hand off and clean up.
The full reference is in the module’s README.