Skip to content
This repository has been archived by the owner on Nov 12, 2024. It is now read-only.

Commit

Permalink
docs: upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
planetscale-actions-bot committed Sep 20, 2023
1 parent 3736534 commit b2a50c6
Showing 1 changed file with 57 additions and 36 deletions.
93 changes: 57 additions & 36 deletions docs/tutorials/go-boost-guide.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 'Go query caching with PlanetScale Boost'
subtitle: 'Learn how to use PlanetScale Boost in a Go application.'
date: '2022-11-15'
date: '2023-09-19'
---

This guide will walk you through two methods to connect to your database using the [PlanetScale Boost query caching feature](/docs/concepts/query-caching-with-planetscale-boost) in Go. We'll first go over a simple example showing how to enable PlanetScale Boost for all queries, and then expand on it to create a separate connection that has the query cache enabled.
Expand All @@ -14,9 +14,11 @@ Below is a simple code snippet showing how to connect to a PlanetScale database.
package main

import (
"context"
"database/sql"
"log"
"os"
"time"

_ "github.com/go-sql-driver/mysql"
)
Expand All @@ -28,29 +30,30 @@ func main() {
}
defer db.Close()

if err := db.Ping(); err != nil {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

if err := db.PingContext(ctx); err != nil {
log.Fatalf("failed to ping: %v", err)
}

log.Println("Successfully connected to PlanetScale!")
}
```

In order for the connection to direct queries through your query cache, you’ll need to set the `@@boost_cached_queries` session variable. You may do so with the following query through your instance of `*sql.DB`:

```go
_, err := db.Exec("SET @@boost_cached_queries = true")
```
In order for the connection to direct queries through your query cache, you’ll need to set the `@@boost_cached_queries` session variable. Because a Go `*sql.DB` is a connection _pool_, you must fetch a _single connection from the pool_ in order to safely modify its session state.

An updated version of the full code snippet might look like this:

```go
package main

import (
"context"
"database/sql"
"log"
"os"
"time"

_ "github.com/go-sql-driver/mysql"
)
Expand All @@ -62,12 +65,21 @@ func main() {
}
defer db.Close()

// Enable query caching on the session.
if _, err := db.Exec("SET @@boost_cached_queries = true"); err != nil {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

// Fetch a connection from the pool and enable query caching in its session.
conn, err := db.Conn(ctx)
if err != nil {
log.Fatalf("failed to get connection: %v", err)
}
defer conn.Close()

if _, err := conn.ExecContext(ctx, "SET @@boost_cached_queries = true"); err != nil {
log.Fatalf("failed to enable boost: %v", err)
}

if err := db.Ping(); err != nil {
if err := conn.PingContext(ctx); err != nil {
log.Fatalf("failed to ping: %v", err)
}

Expand All @@ -79,61 +91,70 @@ Using this method, all of your queries will be run through the boosted connectio

## Set up multiple connections

Our recommended strategy for working with PlanetScale Boost is to use two separate connections so you can be explicit when executing your queries. Below is an updated version of the snippet with an additional function that enables query caching on a database connection:
Our recommended strategy for working with PlanetScale Boost is to use multiple separate connections so you can be explicit when executing your queries. Below is an updated version of the snippet that manages the use of PlanetScale Boost on individual database connections from the pool.

```go
package main

import (
"context"
"database/sql"
"fmt"
"log"
"os"
"time"

_ "github.com/go-sql-driver/mysql"
)

func main() {
// Open a non-caching database connection.
db, err := openDB(os.Getenv("DSN"), false)
db, err := sql.Open("mysql", os.Getenv("DSN"))
if err != nil {
log.Fatalf("failed to connect: %v", err)
}
defer db.Close()

if err := db.Ping(); err != nil {
log.Fatalf("failed to ping: %v", err)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

// Fetch a connection from the pool and explicitly disable query caching.
//
// For a long-lived application, we don't know the session state of the
// connection prior to fetching it from the pool. The safest approach is to
// explicitly set the session variables each time a connection is fetched
// from the pool.
//
// Important: make sure to return the connections to the pool by deferring
// conn.Close, see: https://pkg.go.dev/database/sql#DB.Conn
conn, err := db.Conn(ctx)
if err != nil {
log.Fatalf("failed to get connection: %v", err)
}
defer conn.Close()

log.Println("Successfully connected to PlanetScale!")
if _, err := conn.ExecContext(ctx, "SET @@boost_cached_queries = false"); err != nil {
log.Fatalf("failed to disable boost on connection: %v", err)
}

// Open a caching database connection.
cacheDB, err := openDB(os.Getenv("DSN"), true)
// Fetch a second connection from the pool and enable query caching. See the
// notes above regarding session state and connection pool management.
cachingConn, err := db.Conn(ctx)
if err != nil {
log.Fatalf("failed to connect with caching: %v", err)
log.Fatalf("failed to get caching connection: %v", err)
}
defer cacheDB.Close()
defer cachingConn.Close()

if err := cacheDB.Ping(); err != nil {
log.Fatalf("failed to ping with caching: %v", err)
if _, err := cachingConn.ExecContext(ctx, "SET @@boost_cached_queries = true"); err != nil {
log.Fatalf("failed to enable boost on caching connection: %v", err)
}

log.Println("Successfully connected to PlanetScale with query caching enabled!")
}

func openDB(dsn string, caching bool) (*sql.DB, error) {
db, err := sql.Open("mysql", dsn)
if err != nil {
return nil, fmt.Errorf("failed to connect: %v", err)
if err := conn.PingContext(ctx); err != nil {
log.Fatalf("failed to ping: %v", err)
}

// Optionally enable query caching on the session.
if caching {
if _, err := db.Exec("SET @@boost_cached_queries = true"); err != nil {
return nil, fmt.Errorf("failed to enable boost: %v", err)
}
if err := cachingConn.PingContext(ctx); err != nil {
log.Fatalf("failed to ping with caching: %v", err)
}

return db, nil
log.Println("Successfully connected to PlanetScale!")
}
```

0 comments on commit b2a50c6

Please sign in to comment.