66 lines
1.3 KiB
Go
66 lines
1.3 KiB
Go
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
|
|
}
|