Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOCS-1069: Document API methods for Session and SessionManager #1752

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 115 additions & 5 deletions docs/program/apis/sessions.md → docs/program/apis/session-manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ weight: 20
type: "docs"
description: "How to use the session management API with Viam's Client SDKs."
tags: ["client", "sdk", "viam-server", "networking", "apis", "robot api", "session", "sessions", "session management"]
aliases:
/program/apis/sessions/
---

When controlling a robot or fleet with Viam, you want a way to understand the presence of the clients that are communicating with and authenticated to each robot's `viam-server`.
The period of time during which these clients are present is called a *session*.
The period of time during which these clients are present is called a *session.*
Sessions each have [their own API](/program/apis/session/), which is a client of both `viam-server` and the session management API.

Session management:

Expand All @@ -20,10 +23,10 @@ Session management allows for safer operation of robots that physically move.
For example, imagine a wheeled rover gets a [`SetPower()`](/components/base/#setpower) command as the last input from a client before the connection to the robot is interrupted.
Without session management, the API request from the client sets the flow of electricity to the motors of the robot and then does not time out, causing the robot to continue driving forever, colliding with objects and people.

With default configuration, sessions are automatically managed for you with Viam's `SessionsClient`.
If you want to manage sessions yourself, use Viam's sessions management API.
With default configuration, sessions are automatically managed for you with Viam's session management API's default `SessionsClient`.
If you want to manage sessions yourself, use Viam's session management API.

### The `SessionsClient`
### What is a `SessionsClient`?

A Viam robot has many clients because a client is anything that is receiving the information served by `viam-server` running on the robot, which includes the primary part, sub-parts, client SDKs, and more.
A *client* of a Viam robot could be an SDK script controlling the robot, an input controller, or just the different resources on the robot talking amongst themselves.
Expand Down Expand Up @@ -126,6 +129,113 @@ disableSessions: true
{{% /tab %}}
{{% /tabs %}}

This option allows you to have full control over sessions management.
This option allows you to have full control over session management.
After disabling the client, you must now manage each of your sessions manually with the session management API.
You can do this with Viam's [client SDKs](https://pkg.go.dev/go.viam.com/rdk/session).

## API

The `SessionManager` API built-in to the [Robot API](/program/apis/robot/) supports the following methods:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs documentation on NewSessionManager() in robot API to be functional-- sme review may help clear up some confusion on my end

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added, then removed,NewSessionManager() instantiation of mySessionManager-- unsure whether that should be in there or not. How would a user most simply request to the default session manager API with what we have set up in the RDK? @dgottlieb

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, this SessionManager structure is used by the viam-server running on a robot to track and time out/call Stop robot parts when heartbeats stop coming in.

Client code using the Go SDK wouldn't see anything happen if they were to try using this object.

That said, the documentation for these methods is 100% correct!


{{< readfile "/static/include/program/apis/session-manager.md" >}}

### Start

Create a new session that expects at least one heartbeat within the configured window.

**Parameters:**

- `ctx` [(Context)](https://pkg.go.dev/context): A Context carries a deadline, a cancellation signal, and other values across API boundaries.
- `heartbeatWindow` [(time.Duration)](https://pkg.go.dev/time#Duration): The heartbeat window you want this `SessionManager` to follow for this session. The window is the elapsed time between two instants as an [int64](https://pkg.go.dev/builtin#int64) nanosecond count. The representation limits the largest representable duration to approximately 290 years

**Returns:**

- [(*Session)](https://pkg.go.dev/go.viam.com/rdk/robot#SessionManager): A new session.
- [(error)](https://pkg.go.dev/builtin#error): An error, if one occurred.

For more information, see the [Go SDK Docs](https://pkg.go.dev/go.viam.com/rdk/robot#SessionManager.Start).

``` go
newSession, err := mySessionManager.Start(context.Background(), nil)
```

### All

Get all sessions that are actively being held by this `SessionManager`.

**Parameters:**

- None

**Returns:**

- [([]*Session)](https://pkg.go.dev/go.viam.com/rdk/session#Session): All active sessions associated with this `SessionManager`.

For more information, see the [Go SDK Docs](https://pkg.go.dev/go.viam.com/rdk/robot#SessionManager.All).

``` go
sessions := mySessionManager.All(context.Background(), nil)
```

### FindByID

Find a session by the given ID.
If found, trigger a heartbeat, extending the lifetime of the session.

**Parameters:**

- `ctx` [(Context)](https://pkg.go.dev/context): A Context carries a deadline, a cancellation signal, and other values across API boundaries.
- `id` [(uuid.UUID)](https://pkg.go.dev/github.com/google/uuid#UUID): The client's UUID associated with this session.
- `ownerID` [(string)](https://pkg.go.dev/builtin#string): The client's ownerID associated with this session.
If ownerID is in use but the session in question has a different owner, this is a security violation and Viam reports back that no session is found.

**Returns:**

- [(*SessionManager)](https://pkg.go.dev/go.viam.com/rdk/robot#SessionManager): A new manager for holding sessions.
- [(error)](https://pkg.go.dev/builtin#error): An error, if one occurred.

For more information, see the [Go SDK Docs](https://pkg.go.dev/go.viam.com/rdk/robot#SessionManager.Start).

``` go
newSession, err := mySessionManager.Start(context.Background(), uuid, ownerID)
```

### AssociateResource

Associate a session ID to a monitored resource so that when a session expires:

- If a resource is currently associated with that ID based on the order of AssociateResource calls, then it will have its resource stopped.
- If id is `uuid.Nil`, this has no effect other than disassociation with a session. Be sure to include any remote information in the name.

**Parameters:**

- `id` [(uuid.UUID)](https://pkg.go.dev/github.com/google/uuid#UUID): The client's UUID associated with this session.
- `resourceName` [(resource.Name)](https://pkg.go.dev/go.viam.com/rdk/resource#Name): The `name` you have configured for this resource on your robot.

**Returns:**

- None

For more information, see the [Go SDK Docs](https://pkg.go.dev/go.viam.com/rdk/robot#SessionManager.AssociateResource).

``` go
newSession, err := mySessionManager.AssociateResource(uuid.Nil, "my_base")
```

### Close

Stop the session manager without directing any sessions to expire.

**Parameters:**

- None

**Returns:**

- None

For more information, see the [Go SDK Docs](https://pkg.go.dev/go.viam.com/rdk/robot#SessionManager.Start).

``` go
mySessionManager.Close()
```
100 changes: 100 additions & 0 deletions docs/program/apis/session.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: "Monitor resource sessions with the Session API"
linkTitle: "Session API"
weight: 20
type: "docs"
description: "Safety monitor resources and attach contexts to sessions with the Session API."
tags: ["client", "sdk", "viam-server", "networking", "apis", "robot api", "session", "sessions", "session management"]
---

When controlling a robot or fleet with Viam, you want a way to understand the presence of the clients that are communicating with and authenticated to each robot's `viam-server`.
The period of time during which these clients are present is called a *session*.

## API

The `Session` API supports the following methods:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question for @dgottlieb or any SME who has a better idea of what's going on in the RDK than I do: is this correct? Or should this all be replaced with https://pkg.go.dev/go.viam.com/[email protected]/session#Session as these are just the methods the session package offers and the interface for the type itself has different methods (Active, Heartbeat, etc.). Should both be on here? Apologies for the confusion

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, for posterity, these are internal data types that are not client facing.


{{< readfile "/static/include/program/apis/session.md" >}}

{{% alert title="Tip" color="tip" %}}

The following code examples assume that you have a robot configured with a [base component](/components/base/), and that you add the required code to connect to your robot and import any required packages, including the `sessions` package, at the top of your client file.
Go to your robot's **Code Sample** tab on the [Viam app](https://app.viam.com) for boilerplate code to connect to your robot.

{{% /alert %}}

### SafetyMonitor

Safety monitor this target {{< glossary_tooltip term_id="resource" text="resource" >}} so that, if it exists, if this session ends as the last session to monitor it, the `SessionManager` attempts to stop the resource by calling the `Stop()` method of the resource API.

Do not call this method from the resource being monitored itself, but instead from another client, like another resource, that controls the monitored resource on behalf of some request or routine.
For example, it would be appropriate for a remote [input controller](/components/input-controller/) resource to call a `SafetyMonitor()` on a base that it is remotely controlling the motion of.

In the context of a gRPC handled request, this function can only be called before the first response is sent back.
In the case of unary, it can only be called before the handler returns.

**Parameters:**

- `ctx` [(Context)](https://pkg.go.dev/context): A Context carries a deadline, a cancellation signal, and other values across API boundaries.
- `target` [(resource.Resource)](https://pkg.go.dev/go.viam.com/rdk/resource#Resource): The target resource.

**Returns:**

- None

For more information, see the [Go SDK Docs](https://pkg.go.dev/go.viam.com/rdk/session#SafetyMonitor).

```go
myBase, err := base.FromRobot(robot, "my_base")

// Signal to the session that the given target resource should be safety monitered.
session = session.SafetyMonitor(ctx, myBase)
```

### SafetyMonitorResourceName

Safety monitor this target {{< glossary_tooltip term_id="resource" text="resource" >}} so that, if it exists, if this session ends as the last session to monitor it, the `SessionManager` attempts to stop the resource by calling the `Stop()` method of the resource API.

Do not call this method from the resource being monitored itself, but instead from another client, like another resource, that controls the monitored resource on behalf of some request or routine.
For example, it would be appropriate for a remote [input controller](/components/input-controller/) resource to call a `SafetyMonitor()` on a base that it is remotely controlling the motion of.

In the context of a gRPC handled request, this function can only be called before the first response is sent back.
In the case of unary, it can only be called before the handler returns.

**Parameters:**

- `ctx` [(Context)](https://pkg.go.dev/context): A Context carries a deadline, a cancellation signal, and other values across API boundaries.
- `targetName` [(resource.Name)](https://pkg.go.dev/go.viam.com/rdk/resource#Name): The `name` you have set for the resource in configuration.

**Returns:**

- None

For more information, see the [Go SDK Docs](https://pkg.go.dev/go.viam.com/rdk/session#SafetyMonitorResourceName).

```go
myBase, err := base.FromRobot(robot, "my_base")

// Signal to the session that the given target resource should be safety monitered.
session = session.SafetyMonitor(ctx, "my_base")
```

### ToContext

Attach a session to the given context.

**Parameters:**

- `ctx` [(Context)](https://pkg.go.dev/context): A Context carries a deadline, a cancellation signal, and other values across API boundaries.
- `sess` [(*Session)](https://pkg.go.dev/go.viam.com/rdk/session#Session): The session object that you wish to attach to this context.

**Returns:**

- `ctx` [(Context)](https://pkg.go.dev/context): A Context carries a deadline, a cancellation signal, and other values across API boundaries.

For more information, see the [Go SDK Docs](https://pkg.go.dev/go.viam.com/rdk/session#ToContext).

```go
// Attach session "my session" to the given Context
session = session.ToContext(context.Background(), my_session)
```
7 changes: 7 additions & 0 deletions static/include/program/apis/session-manager.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Method Name | Description
----------- | -----------
[`Start`](/program/apis/sessions/#start) | Create a new session that expects at least one heartbeat within the configured window.
[`All`](/program/apis/sessions/#all) | Get all active sessions.
[`FindByID`](/program/apis/sessions/#findbyid) | Find a session by the given ID. If found, trigger a heartbeat and extend the lifetime of the session.
[`AssociateResource`](/program/apis/sessions/#associateresource) | Associate a session ID to a monitored resource. All associated resources will be stopped with this session is expired.
[`Close`](/program/apis/sessions/#close) | Stop the session manager without directing any sessions to expire.
5 changes: 5 additions & 0 deletions static/include/program/apis/session.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Method Name | Description
----------- | -----------
[`SafetyMonitor`](/program/apis/sessions/#safetymonitor) | Safety monitor this target {{< glossary_tooltip term_id="resource" text="resource" >}} so that if this session ends as the last session to monitor it, the `SessionManager` attempts to stop the resource by calling the `Stop()` method of the resource API.
[`SafetyMonitorResourceName`](/program/apis/sessions/#safetymonitorresourcename) | Safety monitor this target {{< glossary_tooltip term_id="resource" text="resource" >}} so that if this session ends as the last session to monitor it, the `SessionManager` attempts to stop the resource by calling the `Stop()` method of the resource API.
[`ToContext`](/program/apis/sessions/#tocontext) | Attach a session to the given context.
Loading