Files
hse-2026/materials/02-communication/grpc-practice/go-server/storage/server.go
T

66 lines
1.3 KiB
Go
Raw Normal View History

2026-09-14 14:45:31 +03:00
package storage
import (
"context"
"errors"
storagepb "hsegrpc/proto"
"sync"
"time"
"google.golang.org/protobuf/types/known/timestamppb"
)
type Value struct {
payload uint64
updatedAt time.Time
}
// toProto transforms struct into protobuf wrapper.
func (v *Value) toProto() *storagepb.Value {
return &storagepb.Value{
Payload: v.payload,
UpdatedAt: timestamppb.New(v.updatedAt),
}
}
type Server struct {
// Server must implement the Storage protobuf interface.
storagepb.UnimplementedStorageServer
// We use mutex to synchronize access to the value.
valueLocker sync.RWMutex
value Value
}
func NewServer() *Server {
return &Server{}
}
func (s *Server) PutValue(_ context.Context, request *storagepb.PutRequest) (*storagepb.PutResponse, error) {
s.valueLocker.Lock()
defer s.valueLocker.Unlock()
// Check if the given value not empty.
if request.GetValue() == nil {
return nil, errors.New("missed value")
}
s.value = Value{
payload: request.GetValue().GetPayload(),
updatedAt: time.Now(),
}
return &storagepb.PutResponse{
Value: s.value.payload,
}, nil
}
func (s *Server) GetValue(_ context.Context, _ *storagepb.GetRequest) (*storagepb.GetResponse, error) {
s.valueLocker.RLock()
defer s.valueLocker.RUnlock()
return &storagepb.GetResponse{
Value: s.value.toProto(),
}, nil
}