/
model_server.go
120 lines (103 loc) · 3.82 KB
/
model_server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package hail
import (
"context"
"sort"
"github.com/smart-core-os/sc-api/go/traits"
"github.com/smart-core-os/sc-api/go/types"
"github.com/smart-core-os/sc-golang/pkg/resource"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
)
// ModelServer adapts a Model to implement traits.HailApiServer.
type ModelServer struct {
traits.UnimplementedHailApiServer
model *Model
}
func NewModelServer(model *Model) *ModelServer {
return &ModelServer{model: model}
}
func (m *ModelServer) Unwrap() any {
return m.model
}
func (m *ModelServer) Register(server *grpc.Server) {
traits.RegisterHailApiServer(server, m)
}
func (m *ModelServer) CreateHail(_ context.Context, request *traits.CreateHailRequest) (*traits.Hail, error) {
hail := request.Hail
if hail.State == traits.Hail_STATE_UNSPECIFIED {
hail.State = traits.Hail_CALLED
}
return m.model.CreateHail(hail)
}
func (m *ModelServer) GetHail(_ context.Context, request *traits.GetHailRequest) (*traits.Hail, error) {
hail, exists := m.model.GetHail(request.Id, resource.WithReadMask(request.ReadMask))
if !exists {
return nil, status.Errorf(codes.NotFound, "id:%v", request.Id)
}
return hail, nil
}
func (m *ModelServer) UpdateHail(_ context.Context, request *traits.UpdateHailRequest) (*traits.Hail, error) {
return m.model.UpdateHail(request.Hail, resource.WithUpdateMask(request.UpdateMask))
}
func (m *ModelServer) DeleteHail(_ context.Context, request *traits.DeleteHailRequest) (*traits.DeleteHailResponse, error) {
_, err := m.model.DeleteHail(request.Id, resource.WithAllowMissing(request.AllowMissing))
return &traits.DeleteHailResponse{}, err
}
func (m *ModelServer) PullHail(request *traits.PullHailRequest, server traits.HailApi_PullHailServer) error {
for change := range m.model.PullHail(server.Context(), request.Id, resource.WithReadMask(request.ReadMask), resource.WithUpdatesOnly(request.UpdatesOnly)) {
err := server.Send(&traits.PullHailResponse{Changes: []*traits.PullHailResponse_Change{
{Name: request.Name, ChangeTime: timestamppb.New(change.ChangeTime), Hail: change.Value},
}})
if err != nil {
return err
}
}
return nil
}
func (m *ModelServer) ListHails(_ context.Context, request *traits.ListHailsRequest) (*traits.ListHailsResponse, error) {
pageToken := &types.PageToken{}
if err := decodePageToken(request.PageToken, pageToken); err != nil {
return nil, err
}
lastKey := pageToken.GetLastResourceName() // the key() of the last item we sent
pageSize := capPageSize(int(request.GetPageSize()))
sortedItems := m.model.ListHails(resource.WithReadMask(request.ReadMask))
nextIndex := 0
if lastKey != "" {
nextIndex = sort.Search(len(sortedItems), func(i int) bool {
return sortedItems[i].Id > lastKey
})
}
result := &traits.ListHailsResponse{
TotalSize: int32(len(sortedItems)),
}
upperBound := nextIndex + pageSize
if upperBound > len(sortedItems) {
upperBound = len(sortedItems)
pageToken = nil
} else {
pageToken.PageStart = &types.PageToken_LastResourceName{
LastResourceName: sortedItems[upperBound-1].Id,
}
}
var err error
result.NextPageToken, err = encodePageToken(pageToken)
if err != nil {
return nil, err
}
result.Hails = sortedItems[nextIndex:upperBound]
return result, nil
}
func (m *ModelServer) PullHails(request *traits.PullHailsRequest, server traits.HailApi_PullHailsServer) error {
for change := range m.model.PullHails(server.Context(), resource.WithReadMask(request.ReadMask), resource.WithUpdatesOnly(request.UpdatesOnly)) {
err := server.Send(&traits.PullHailsResponse{Changes: []*traits.PullHailsResponse_Change{
{Name: request.Name, Type: change.ChangeType, ChangeTime: timestamppb.New(change.ChangeTime), OldValue: change.OldValue, NewValue: change.NewValue},
}})
if err != nil {
return err
}
}
return nil
}