This guide demonstrates the basic lifecycle of a Reverb session: starting a server with a table, connecting a client, inserting simple data, and using a trajectory_writer for complex data structures.
1. Start a Server
Initialize a reverb.Server with one or more reverb.Table objects. Tables require a name, a sampler (how to pick items), a remover (how to handle overflow), a max_size, and a rate_limiter.
2. Connect a Client
Use reverb.Client with the server's address (e.g., localhost:{server.port}).
3. Insert Data
- Simple Insertion: Use
client.insert(data, priorities={'table_name': priority}). - Trajectory Writing: For items that reference multiple data elements (like sequences), use
client.trajectory_writer(). This allows you to append data elements and then create an item that references slices of that history.
4. Sample Data
Use client.sample('table_name', num_samples=N) to get a generator of sampled items.
import reverb
# 1. Start a Server
server = reverb.Server(tables=[
reverb.Table(
name='my_table',
sampler=reverb.selectors.Uniform(),
remover=reverb.selectors.Fifo(),
max_size=100,
rate_limiter=reverb.rate_limiters.MinSize(1)),
],
)
# 2. Connect a Client
client = reverb.Client(f'localhost:{server.port}')
print(client.server_info())
# 3. Write simple data
client.insert([0, 1], priorities={'my_table': 1.0})
# 3b. Write complex trajectories
with client.trajectory_writer(num_keep_alive_refs=3) as writer:
writer.append({'a': 2, 'b': 12})
writer.append({'a': 3, 'b': 13})
writer.append({'a': 4, 'b': 14})
writer.create_item(
table='my_table',
priority=1.0,
trajectory={
'a': writer.history['a'][:],
'b': writer.history['b'][:],
})
writer.flush()
# 4. Sample data
print(list(client.sample('my_table', num_samples=2)))