Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
63 changes: 62 additions & 1 deletion .github/workflows/client-sdk-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,69 @@ jobs:
cargo build --example simple_producer
cargo build --example simple_consumer

go-client:
name: Go Client SDK
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
cache-dependency-path: clients/go/prism-client/go.sum

- name: Install protobuf compiler
run: |
sudo apt-get update
sudo apt-get install -y protobuf-compiler
protoc --version

- name: Install protoc-gen-go plugins
run: |
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

- name: Generate protobuf code
working-directory: clients/go/prism-client
run: ./gen-proto.sh

- name: Check formatting
working-directory: clients/go/prism-client
run: |
gofmt -l . | tee /tmp/gofmt.out
if [ -s /tmp/gofmt.out ]; then
echo "❌ Code not formatted. Run: go fmt ./..."
exit 1
fi

- name: Download dependencies
working-directory: clients/go/prism-client
run: go mod download

- name: Verify dependencies
working-directory: clients/go/prism-client
run: go mod verify

- name: Build library
working-directory: clients/go/prism-client
run: go build -v ./...

- name: Run vet
working-directory: clients/go/prism-client
run: go vet ./...

- name: Build multicast canary
working-directory: clients/go/prism-client/examples/multicast-canary
run: go build -v -o /tmp/go-multicast-canary .

# Status check that's required for PR approval
# This aggregates all client SDK checks
client-sdk-status:
name: Client SDK Status Check
runs-on: ubuntu-latest
needs: [rust-client]
needs: [rust-client, go-client]
if: always()
steps:
- name: Check all jobs status
Expand All @@ -82,4 +139,8 @@ jobs:
echo "❌ Rust client SDK checks failed"
exit 1
fi
if [[ "${{ needs.go-client.result }}" == "failure" ]]; then
echo "❌ Go client SDK checks failed"
exit 1
fi
echo "✅ All client SDK checks passed"
30 changes: 30 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,36 @@ build-keyvalue-runner: ## Build keyvalue pattern runner

build-patterns: build-consumer-runner build-producer-runner build-multicast-registry-runner build-keyvalue-runner ## Build all pattern runners

build-go-client: ## Build Go client SDK library
$(call print_blue,Building Go client SDK...)
@cd clients/go/prism-client && go build ./...
$(call print_green,Go client SDK built successfully)

build-go-client-canary: ## Build Go client multicast canary example
$(call print_blue,Building Go client multicast canary...)
@mkdir -p $(BINARIES_DIR)
@cd clients/go/prism-client/examples/multicast-canary && go build -o $(BINARIES_DIR)/go-multicast-canary .
$(call print_green,Go multicast canary built: $(BINARIES_DIR)/go-multicast-canary)

build-rust-client-canary: ## Build Rust client canary example
$(call print_blue,Building Rust client canary...)
@mkdir -p $(BINARIES_DIR)
@cd clients/rust/prism-client && CARGO_TARGET_DIR=$(RUST_TARGET_DIR) cargo build --release --example canary
@cp $(RUST_TARGET_DIR)/release/examples/canary $(BINARIES_DIR)/rust-client-canary
$(call print_green,Rust client canary built: $(BINARIES_DIR)/rust-client-canary)

build-rust-client-examples: ## Build all Rust client examples
$(call print_blue,Building all Rust client examples...)
@mkdir -p $(BINARIES_DIR)
@cd clients/rust/prism-client && CARGO_TARGET_DIR=$(RUST_TARGET_DIR) cargo build --release --examples
@cp $(RUST_TARGET_DIR)/release/examples/canary $(BINARIES_DIR)/rust-client-canary
@cp $(RUST_TARGET_DIR)/release/examples/hello_world $(BINARIES_DIR)/rust-client-hello-world
@cp $(RUST_TARGET_DIR)/release/examples/simple_producer $(BINARIES_DIR)/rust-client-simple-producer
@cp $(RUST_TARGET_DIR)/release/examples/simple_consumer $(BINARIES_DIR)/rust-client-simple-consumer
$(call print_green,All Rust client examples built in $(BINARIES_DIR)/)

build-client-sdks: build-go-client build-go-client-canary build-rust-client-examples ## Build all client SDKs and examples

build-dev: ## Build all components in debug mode (faster)
$(call print_blue,Building in debug mode...)
@mkdir -p $(BINARIES_DIR)
Expand Down
151 changes: 151 additions & 0 deletions clients/go/prism-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Prism Go Client SDK

Official Go client library for interacting with Prism data access patterns.

## Features

- **Simple API**: Idiomatic Go with context support
- **Pattern-First**: Producer, Consumer, KeyValue, Multicast Registry patterns
- **Type-Safe**: Protobuf-based type safety
- **Production-Ready**: Connection pooling, automatic retries, graceful shutdown

## Quick Start

```go
package main

import (
"context"
"fmt"

prism "github.com/prism/prism-client/client"
)

func main() {
// Connect to Prism proxy
client, err := prism.Connect("localhost:8980")
if err != nil {
panic(err)
}
defer client.Close()

ctx := context.Background()

// Use KeyValue pattern
kv := client.KeyValue("cache")
err = kv.Set(ctx, "user:42", []byte("alice"))

// Use Producer pattern
producer := client.Producer("orders")
err = producer.Publish(ctx, "new-orders", []byte("order-123"))

// Use Consumer pattern
consumer := client.Consumer("orders")
messages, err := consumer.Subscribe(ctx, "new-orders")
for msg := range messages {
fmt.Printf("Received: %s\n", msg.Payload)
msg.Ack(ctx)
}
}
```

## Installation

```bash
go get github.com/prism/prism-client
```

## Documentation

See [examples/](examples/) for more detailed usage examples.

## Architecture

The client follows the same architecture as the Rust client SDK:

- **Synchronous by Default**: Go's natural model with goroutines
- **Context-Aware**: All operations accept `context.Context` for cancellation
- **Pattern Abstraction**: High-level APIs hide gRPC complexity
- **Connection Multiplexing**: Single gRPC connection per client

## Patterns

### KeyValue

Simple key-value operations with optional TTL support:

```go
kv := client.KeyValue("cache")
kv.Set(ctx, "key", []byte("value"))
kv.SetWithTTL(ctx, "session", []byte("data"), 300) // 5 min TTL
value, err := kv.Get(ctx, "key")
exists, err := kv.Exists(ctx, "key")
kv.Delete(ctx, "key")
```

### Producer

Publish messages to topics:

```go
producer := client.Producer("events")
producer.Publish(ctx, "user-events", []byte("user-login"))
producer.PublishWithMetadata(ctx, "user-events", []byte("data"),
map[string]string{"user_id": "alice"})
```

### Consumer

Subscribe to messages from topics:

```go
consumer := client.Consumer("events")
messages, err := consumer.Subscribe(ctx, "user-events")
for msg := range messages {
fmt.Printf("Received: %s\n", msg.Payload)
msg.Ack(ctx)
}
```

### Multicast Registry

Register identities and broadcast to filtered groups:

```go
registry := client.Registry("presence")

// Register identity
registry.Register(ctx, "user-alice-123", map[string]interface{}{
"user_id": "alice",
"status": "online",
"room": "engineering",
}, 300)

// Enumerate identities
identities, err := registry.Enumerate(ctx, map[string]interface{}{
"room": "engineering",
"status": "online",
})

// Multicast to filtered group
registry.Multicast(ctx, map[string]interface{}{
"room": "engineering",
}, []byte("Hello team!"))
```

## Testing

```bash
# Run unit tests
go test ./...

# Run with race detector
go test -race ./...

# Run integration tests (requires running proxy)
go test -tags=integration ./...
```

## License

Apache 2.0
Loading
Loading