HW14 Completed

hw12_13_14_15_calendar
Andrey Ivanov 2020-11-23 17:18:30 +03:00 committed by tiburon
parent 4976188993
commit 63c008f963
6 changed files with 178 additions and 20 deletions

View File

@ -11,6 +11,7 @@ import "google/protobuf/empty.proto";
service grpc { service grpc {
rpc GetNotifications(google.protobuf.Empty) returns (GetRsp) {} rpc GetNotifications(google.protobuf.Empty) returns (GetRsp) {}
rpc SetNotified(SetReq) returns (google.protobuf.Empty) {} rpc SetNotified(SetReq) returns (google.protobuf.Empty) {}
rpc PurgeOldEvents(PurgeReq) returns (PurgeResp) {}
} }
message GetRsp { message GetRsp {
@ -20,6 +21,13 @@ message GetRsp {
message SetReq { message SetReq {
int64 ID = 1; int64 ID = 1;
} }
message PurgeReq {
int64 OlderThenDays = 1;
}
message PurgeResp {
int64 Qty = 1;
}
message Event { message Event {
int64 ID = 1; int64 ID = 1;

View File

@ -104,6 +104,84 @@ func (m *SetReq) GetID() int64 {
return 0 return 0
} }
type PurgeReq struct {
OlderThenDays int64 `protobuf:"varint,1,opt,name=OlderThenDays,proto3" json:"OlderThenDays,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PurgeReq) Reset() { *m = PurgeReq{} }
func (m *PurgeReq) String() string { return proto.CompactTextString(m) }
func (*PurgeReq) ProtoMessage() {}
func (*PurgeReq) Descriptor() ([]byte, []int) {
return fileDescriptor_afa6debe97205904, []int{2}
}
func (m *PurgeReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PurgeReq.Unmarshal(m, b)
}
func (m *PurgeReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PurgeReq.Marshal(b, m, deterministic)
}
func (m *PurgeReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_PurgeReq.Merge(m, src)
}
func (m *PurgeReq) XXX_Size() int {
return xxx_messageInfo_PurgeReq.Size(m)
}
func (m *PurgeReq) XXX_DiscardUnknown() {
xxx_messageInfo_PurgeReq.DiscardUnknown(m)
}
var xxx_messageInfo_PurgeReq proto.InternalMessageInfo
func (m *PurgeReq) GetOlderThenDays() int64 {
if m != nil {
return m.OlderThenDays
}
return 0
}
type PurgeResp struct {
Qty int64 `protobuf:"varint,1,opt,name=Qty,proto3" json:"Qty,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PurgeResp) Reset() { *m = PurgeResp{} }
func (m *PurgeResp) String() string { return proto.CompactTextString(m) }
func (*PurgeResp) ProtoMessage() {}
func (*PurgeResp) Descriptor() ([]byte, []int) {
return fileDescriptor_afa6debe97205904, []int{3}
}
func (m *PurgeResp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PurgeResp.Unmarshal(m, b)
}
func (m *PurgeResp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PurgeResp.Marshal(b, m, deterministic)
}
func (m *PurgeResp) XXX_Merge(src proto.Message) {
xxx_messageInfo_PurgeResp.Merge(m, src)
}
func (m *PurgeResp) XXX_Size() int {
return xxx_messageInfo_PurgeResp.Size(m)
}
func (m *PurgeResp) XXX_DiscardUnknown() {
xxx_messageInfo_PurgeResp.DiscardUnknown(m)
}
var xxx_messageInfo_PurgeResp proto.InternalMessageInfo
func (m *PurgeResp) GetQty() int64 {
if m != nil {
return m.Qty
}
return 0
}
type Event struct { type Event struct {
ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
Title string `protobuf:"bytes,2,opt,name=Title,proto3" json:"Title,omitempty"` Title string `protobuf:"bytes,2,opt,name=Title,proto3" json:"Title,omitempty"`
@ -118,7 +196,7 @@ func (m *Event) Reset() { *m = Event{} }
func (m *Event) String() string { return proto.CompactTextString(m) } func (m *Event) String() string { return proto.CompactTextString(m) }
func (*Event) ProtoMessage() {} func (*Event) ProtoMessage() {}
func (*Event) Descriptor() ([]byte, []int) { func (*Event) Descriptor() ([]byte, []int) {
return fileDescriptor_afa6debe97205904, []int{2} return fileDescriptor_afa6debe97205904, []int{4}
} }
func (m *Event) XXX_Unmarshal(b []byte) error { func (m *Event) XXX_Unmarshal(b []byte) error {
@ -170,31 +248,37 @@ func (m *Event) GetUserID() int64 {
func init() { func init() {
proto.RegisterType((*GetRsp)(nil), "private.GetRsp") proto.RegisterType((*GetRsp)(nil), "private.GetRsp")
proto.RegisterType((*SetReq)(nil), "private.SetReq") proto.RegisterType((*SetReq)(nil), "private.SetReq")
proto.RegisterType((*PurgeReq)(nil), "private.PurgeReq")
proto.RegisterType((*PurgeResp)(nil), "private.PurgeResp")
proto.RegisterType((*Event)(nil), "private.Event") proto.RegisterType((*Event)(nil), "private.Event")
} }
func init() { proto.RegisterFile("grpcserver.proto", fileDescriptor_afa6debe97205904) } func init() { proto.RegisterFile("grpcserver.proto", fileDescriptor_afa6debe97205904) }
var fileDescriptor_afa6debe97205904 = []byte{ var fileDescriptor_afa6debe97205904 = []byte{
// 286 bytes of a gzipped FileDescriptorProto // 351 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x4f, 0x6b, 0x32, 0x31, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0x41, 0x6b, 0xea, 0x50,
0x10, 0x87, 0x5d, 0xff, 0xec, 0x8b, 0x23, 0xf8, 0x4a, 0x28, 0x12, 0xb6, 0x87, 0x2e, 0x7b, 0x28, 0x10, 0x85, 0x8d, 0xd1, 0xbc, 0xe7, 0xc8, 0xf3, 0xf9, 0x86, 0x87, 0x84, 0x94, 0xd2, 0x10, 0x4a,
0x7b, 0x8a, 0xc5, 0x5e, 0x7a, 0xe9, 0xa5, 0xac, 0x88, 0x97, 0x1e, 0xa2, 0xbd, 0xf4, 0xb6, 0xda, 0xc9, 0x2a, 0x8a, 0xdd, 0xb4, 0x8b, 0x6e, 0x4a, 0x44, 0xdc, 0xd4, 0x36, 0xda, 0x4d, 0x77, 0x51,
0x51, 0x02, 0x6a, 0xd2, 0x64, 0x5c, 0xe8, 0xa9, 0x5f, 0xbd, 0x98, 0xec, 0xb6, 0x60, 0xe9, 0x71, 0xc7, 0x34, 0x10, 0x4d, 0x7a, 0xef, 0x28, 0xf8, 0xd7, 0xfa, 0xeb, 0x4a, 0x72, 0x13, 0x4b, 0x2d,
0xe6, 0xf7, 0x64, 0x32, 0x4f, 0x02, 0xa3, 0x9d, 0x35, 0x1b, 0x87, 0xb6, 0x42, 0x2b, 0x8c, 0xd5, 0xdd, 0xe5, 0x9e, 0x39, 0x73, 0x0e, 0xf3, 0x11, 0xe8, 0x46, 0x22, 0x5b, 0x4a, 0x12, 0x7b, 0x12,
0xa4, 0xd9, 0x3f, 0x63, 0x55, 0x55, 0x12, 0x26, 0x37, 0x3b, 0xad, 0x77, 0x7b, 0x9c, 0xf8, 0xf6, 0x5e, 0x26, 0x52, 0x4e, 0xf1, 0x57, 0x26, 0xe2, 0x7d, 0xc8, 0x64, 0x5d, 0x44, 0x69, 0x1a, 0x25,
0xfa, 0xb4, 0x9d, 0x90, 0x3a, 0xa0, 0xa3, 0xf2, 0x60, 0x02, 0x99, 0x5c, 0x5f, 0x02, 0x78, 0x30, 0xd4, 0x2f, 0xe4, 0xc5, 0x6e, 0xdd, 0xe7, 0x78, 0x43, 0x92, 0xc3, 0x4d, 0xa6, 0x9c, 0xd6, 0xd9,
0xf4, 0x11, 0xc2, 0xec, 0x0e, 0xe2, 0x39, 0x92, 0x74, 0x86, 0xdd, 0x42, 0x3c, 0xab, 0xf0, 0x48, 0xa9, 0x81, 0x36, 0x19, 0x1f, 0xd4, 0xd0, 0x19, 0x80, 0x31, 0x26, 0x0e, 0x64, 0x86, 0x57, 0x60,
0x8e, 0x47, 0x69, 0x27, 0x1f, 0x4c, 0x87, 0xa2, 0xbe, 0x41, 0xf8, 0xb6, 0xac, 0xd3, 0x8c, 0x43, 0x8c, 0xf6, 0xb4, 0x65, 0x69, 0x6a, 0xb6, 0xee, 0xb6, 0x87, 0x1d, 0xaf, 0x6c, 0xf0, 0x0a, 0x39,
0xbc, 0x44, 0x92, 0xf8, 0xce, 0x86, 0xd0, 0x5e, 0x14, 0x3c, 0x4a, 0xa3, 0xbc, 0x23, 0xdb, 0x8b, 0x28, 0xa7, 0x8e, 0x09, 0xc6, 0x8c, 0x38, 0xa0, 0x37, 0xec, 0x40, 0x7d, 0xe2, 0x9b, 0x9a, 0xad,
0x22, 0x3b, 0x41, 0xcf, 0x33, 0x97, 0x01, 0xbb, 0x82, 0xde, 0x4a, 0xd1, 0x1e, 0x79, 0x3b, 0x8d, 0xb9, 0x7a, 0x50, 0x9f, 0xf8, 0xce, 0x00, 0x7e, 0x3f, 0xee, 0x44, 0x44, 0xf9, 0xec, 0x12, 0xfe,
0xf2, 0xbe, 0x0c, 0x05, 0x13, 0xd0, 0x2d, 0x4a, 0x42, 0xde, 0x49, 0xa3, 0x7c, 0x30, 0x4d, 0x44, 0x4c, 0x93, 0x15, 0x89, 0xf9, 0x2b, 0x6d, 0xfd, 0xf0, 0x20, 0x4b, 0xdb, 0x57, 0xd1, 0x39, 0x87,
0x58, 0x53, 0x34, 0x6b, 0x8a, 0x55, 0xe3, 0x21, 0x3d, 0xc7, 0xc6, 0x10, 0xbf, 0x38, 0xb4, 0x8b, 0x56, 0xb9, 0x21, 0x33, 0xec, 0x82, 0xfe, 0xc4, 0x87, 0xd2, 0x98, 0x7f, 0x3a, 0x3b, 0x68, 0x16,
0x82, 0x77, 0xfd, 0xe4, 0xba, 0x9a, 0x7e, 0x42, 0xf7, 0xfc, 0x3a, 0xec, 0x11, 0x46, 0x73, 0xa4, 0xa5, 0xa7, 0x4d, 0xf8, 0x1f, 0x9a, 0xf3, 0x98, 0x13, 0x32, 0xeb, 0xb6, 0xe6, 0xb6, 0x02, 0xf5,
0x67, 0x4d, 0x6a, 0xab, 0x36, 0x25, 0x29, 0x7d, 0x74, 0x6c, 0xfc, 0x6b, 0xea, 0xec, 0x2c, 0x9f, 0x40, 0x0f, 0x1a, 0x7e, 0xc8, 0x64, 0xea, 0xb6, 0xe6, 0xb6, 0x87, 0x96, 0xa7, 0xee, 0xf6, 0xaa,
0xfc, 0xff, 0x96, 0x0b, 0xf6, 0x59, 0x8b, 0x3d, 0xc0, 0x60, 0xd9, 0x1c, 0xc7, 0x37, 0xf6, 0x43, 0xbb, 0xbd, 0x79, 0x05, 0x26, 0x28, 0x7c, 0xd8, 0x03, 0xe3, 0x59, 0x92, 0x98, 0xf8, 0x66, 0xa3,
0x04, 0xdb, 0xe4, 0x8f, 0x51, 0x59, 0xeb, 0xa9, 0xff, 0xda, 0x7c, 0xc6, 0x3a, 0xf6, 0xe1, 0xfd, 0x48, 0x2e, 0x5f, 0xc3, 0x77, 0x0d, 0x1a, 0x39, 0x6f, 0xbc, 0x83, 0xee, 0x98, 0xf8, 0x21, 0xe5,
0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x5f, 0x05, 0xc6, 0xb0, 0x01, 0x00, 0x00, 0x78, 0x1d, 0x2f, 0x43, 0x8e, 0xd3, 0xad, 0xc4, 0xde, 0xb7, 0xd8, 0x51, 0x8e, 0xd3, 0xfa, 0x7b,
0xc4, 0xa5, 0x78, 0x3a, 0x35, 0xbc, 0x81, 0xf6, 0xac, 0x5a, 0xa7, 0x15, 0x7e, 0x3a, 0x14, 0x3f,
0xeb, 0x87, 0x28, 0xa7, 0x86, 0xb7, 0xd0, 0x29, 0xb8, 0x4c, 0x93, 0x95, 0xa2, 0x8e, 0xff, 0x8e,
0xcb, 0x15, 0x62, 0x0b, 0x4f, 0xa5, 0xbc, 0xf4, 0xbe, 0xf5, 0x52, 0xfd, 0x19, 0x0b, 0xa3, 0xc8,
0xbd, 0xfe, 0x08, 0x00, 0x00, 0xff, 0xff, 0x7f, 0xac, 0x01, 0x89, 0x3d, 0x02, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -211,6 +295,7 @@ const _ = grpc.SupportPackageIsVersion4
type GrpcClient interface { type GrpcClient interface {
GetNotifications(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*GetRsp, error) GetNotifications(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*GetRsp, error)
SetNotified(ctx context.Context, in *SetReq, opts ...grpc.CallOption) (*empty.Empty, error) SetNotified(ctx context.Context, in *SetReq, opts ...grpc.CallOption) (*empty.Empty, error)
PurgeOldEvents(ctx context.Context, in *PurgeReq, opts ...grpc.CallOption) (*PurgeResp, error)
} }
type grpcClient struct { type grpcClient struct {
@ -239,10 +324,20 @@ func (c *grpcClient) SetNotified(ctx context.Context, in *SetReq, opts ...grpc.C
return out, nil return out, nil
} }
func (c *grpcClient) PurgeOldEvents(ctx context.Context, in *PurgeReq, opts ...grpc.CallOption) (*PurgeResp, error) {
out := new(PurgeResp)
err := c.cc.Invoke(ctx, "/private.grpc/PurgeOldEvents", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// GrpcServer is the server API for Grpc service. // GrpcServer is the server API for Grpc service.
type GrpcServer interface { type GrpcServer interface {
GetNotifications(context.Context, *empty.Empty) (*GetRsp, error) GetNotifications(context.Context, *empty.Empty) (*GetRsp, error)
SetNotified(context.Context, *SetReq) (*empty.Empty, error) SetNotified(context.Context, *SetReq) (*empty.Empty, error)
PurgeOldEvents(context.Context, *PurgeReq) (*PurgeResp, error)
} }
// UnimplementedGrpcServer can be embedded to have forward compatible implementations. // UnimplementedGrpcServer can be embedded to have forward compatible implementations.
@ -255,6 +350,9 @@ func (*UnimplementedGrpcServer) GetNotifications(ctx context.Context, req *empty
func (*UnimplementedGrpcServer) SetNotified(ctx context.Context, req *SetReq) (*empty.Empty, error) { func (*UnimplementedGrpcServer) SetNotified(ctx context.Context, req *SetReq) (*empty.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method SetNotified not implemented") return nil, status.Errorf(codes.Unimplemented, "method SetNotified not implemented")
} }
func (*UnimplementedGrpcServer) PurgeOldEvents(ctx context.Context, req *PurgeReq) (*PurgeResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method PurgeOldEvents not implemented")
}
func RegisterGrpcServer(s *grpc.Server, srv GrpcServer) { func RegisterGrpcServer(s *grpc.Server, srv GrpcServer) {
s.RegisterService(&_Grpc_serviceDesc, srv) s.RegisterService(&_Grpc_serviceDesc, srv)
@ -296,6 +394,24 @@ func _Grpc_SetNotified_Handler(srv interface{}, ctx context.Context, dec func(in
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _Grpc_PurgeOldEvents_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PurgeReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GrpcServer).PurgeOldEvents(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/private.grpc/PurgeOldEvents",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GrpcServer).PurgeOldEvents(ctx, req.(*PurgeReq))
}
return interceptor(ctx, in, info, handler)
}
var _Grpc_serviceDesc = grpc.ServiceDesc{ var _Grpc_serviceDesc = grpc.ServiceDesc{
ServiceName: "private.grpc", ServiceName: "private.grpc",
HandlerType: (*GrpcServer)(nil), HandlerType: (*GrpcServer)(nil),
@ -308,6 +424,10 @@ var _Grpc_serviceDesc = grpc.ServiceDesc{
MethodName: "SetNotified", MethodName: "SetNotified",
Handler: _Grpc_SetNotified_Handler, Handler: _Grpc_SetNotified_Handler,
}, },
{
MethodName: "PurgeOldEvents",
Handler: _Grpc_PurgeOldEvents_Handler,
},
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},
Metadata: "grpcserver.proto", Metadata: "grpcserver.proto",

View File

@ -29,3 +29,8 @@ func (s Service) GetNotifications(ctx context.Context, e *empty.Empty) (*GetRsp,
func (s Service) SetNotified(ctx context.Context, r *SetReq) (*empty.Empty, error) { func (s Service) SetNotified(ctx context.Context, r *SetReq) (*empty.Empty, error) {
return nil, s.App.Storage.SetNotified(event.ID(r.ID)) return nil, s.App.Storage.SetNotified(event.ID(r.ID))
} }
func (s Service) PurgeOldEvents(ctx context.Context, r *PurgeReq) (*PurgeResp, error) {
q, err := s.App.Storage.PurgeOldEvents(r.OlderThenDays)
return &PurgeResp{Qty: q}, err
}

View File

@ -86,6 +86,19 @@ func (s *Storage) SetNotified(id event.ID) error {
return nil return nil
} }
func (s *Storage) PurgeOldEvents(days int64) (res int64, err error) {
s.Mu.Lock()
defer s.Mu.Unlock()
seconds := time.Duration(days * 24 * 60 * 60)
for k, v := range s.Events {
if v.Date.Before(time.Now().Add(-seconds)) {
delete(s.Events, k)
res++
}
}
return res, err
}
func getEndDate(startDate time.Time, rng string) time.Time { func getEndDate(startDate time.Time, rng string) time.Time {
switch rng { switch rng {
case "DAY": case "DAY":

View File

@ -201,6 +201,17 @@ func (s *Storage) SetNotified(id event.ID) error {
return err return err
} }
func (s *Storage) PurgeOldEvents(days int64) (int64, error) {
r, err := s.db.Exec(
`DELETE from events where date<$1`,
time.Now().Add(-time.Duration(days*24*60*60)),
)
if err != nil {
return 0, err
}
return r.RowsAffected()
}
func getEndDate(startDate time.Time, rng string) time.Time { func getEndDate(startDate time.Time, rng string) time.Time {
switch rng { switch rng {
case "DAY": case "DAY":

View File

@ -26,6 +26,7 @@ type StorageInterface interface {
GetByDate(time.Time, string) (map[event.ID]event.Event, error) GetByDate(time.Time, string) (map[event.ID]event.Event, error)
GetNotifications() (map[event.ID]event.Event, error) GetNotifications() (map[event.ID]event.Event, error)
SetNotified(event.ID) error SetNotified(event.ID) error
PurgeOldEvents(int64) (int64, error)
} }
func NewStore(conf Config) StorageInterface { func NewStore(conf Config) StorageInterface {