github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/cluster/pubsub_batch.go (about) 1 package cluster 2 3 import ( 4 "github.com/asynkron/protoactor-go/actor" 5 "github.com/asynkron/protoactor-go/remote" 6 "google.golang.org/protobuf/proto" 7 ) 8 9 var ( 10 _ remote.RootSerializable = (*PubSubBatch)(nil) 11 _ remote.RootSerializable = (*DeliverBatchRequest)(nil) 12 _ remote.RootSerializable = (*PubSubAutoRespondBatch)(nil) 13 14 _ remote.RootSerialized = (*PubSubBatchTransport)(nil) 15 _ remote.RootSerialized = (*DeliverBatchRequestTransport)(nil) 16 _ remote.RootSerialized = (*PubSubAutoRespondBatchTransport)(nil) 17 ) 18 19 type PubSubBatch struct { 20 Envelopes []proto.Message 21 } 22 23 // Serialize converts a PubSubBatch to a PubSubBatchTransport. 24 func (b *PubSubBatch) Serialize() (remote.RootSerialized, error) { 25 batch := &PubSubBatchTransport{ 26 TypeNames: make([]string, 0), 27 Envelopes: make([]*PubSubEnvelope, 0), 28 } 29 30 for _, envelope := range b.Envelopes { 31 var serializerId int32 32 messageData, typeName, err := remote.Serialize(envelope, serializerId) 33 if err != nil { 34 return nil, err 35 } 36 // batch.TypeNames.IndexOf(typeName) 37 typeIndex := -1 38 for i, t := range batch.TypeNames { 39 if t == typeName { 40 typeIndex = i 41 break 42 } 43 } 44 if typeIndex == -1 { 45 batch.TypeNames = append(batch.TypeNames, typeName) 46 typeIndex = len(batch.TypeNames) - 1 47 } 48 batch.Envelopes = append(batch.Envelopes, &PubSubEnvelope{ 49 MessageData: messageData, 50 TypeId: int32(typeIndex), 51 SerializerId: serializerId, 52 }) 53 } 54 return batch, nil 55 } 56 57 // Deserialize converts a PubSubBatchTransport to a PubSubBatch. 58 func (t *PubSubBatchTransport) Deserialize() (remote.RootSerializable, error) { 59 b := &PubSubBatch{ 60 Envelopes: make([]proto.Message, 0), 61 } 62 63 for _, envelope := range t.Envelopes { 64 message, err := remote.Deserialize(envelope.MessageData, t.TypeNames[envelope.TypeId], envelope.SerializerId) 65 if err != nil { 66 return nil, err 67 } 68 protoMessage, ok := message.(proto.Message) 69 if !ok { 70 panic("message is not proto.Message") 71 } 72 73 b.Envelopes = append(b.Envelopes, protoMessage) 74 } 75 return b, nil 76 } 77 78 type DeliverBatchRequest struct { 79 Subscribers *Subscribers 80 PubSubBatch *PubSubBatch 81 Topic string 82 } 83 84 func (d *DeliverBatchRequest) Serialize() (remote.RootSerialized, error) { 85 rs, err := d.PubSubBatch.Serialize() 86 if err != nil { 87 return nil, err 88 } 89 90 return &DeliverBatchRequestTransport{ 91 Subscribers: d.Subscribers, 92 Batch: rs.(*PubSubBatchTransport), 93 Topic: d.Topic, 94 }, nil 95 } 96 97 func (t *DeliverBatchRequestTransport) Deserialize() (remote.RootSerializable, error) { 98 rs, err := t.Batch.Deserialize() 99 if err != nil { 100 return nil, err 101 } 102 103 return &DeliverBatchRequest{ 104 Subscribers: t.Subscribers, 105 PubSubBatch: rs.(*PubSubBatch), 106 Topic: t.Topic, 107 }, nil 108 } 109 110 var _ actor.MessageBatch = (*PubSubAutoRespondBatch)(nil) 111 112 type PubSubAutoRespondBatch struct { 113 Envelopes []proto.Message 114 } 115 116 // Serialize converts a PubSubAutoRespondBatch to a PubSubAutoRespondBatchTransport. 117 func (b *PubSubAutoRespondBatch) Serialize() (remote.RootSerialized, error) { 118 batch := &PubSubBatch{Envelopes: b.Envelopes} 119 120 rs, err := batch.Serialize() 121 if err != nil { 122 return nil, err 123 } 124 125 return &PubSubAutoRespondBatchTransport{ 126 TypeNames: rs.(*PubSubBatchTransport).TypeNames, 127 Envelopes: rs.(*PubSubBatchTransport).Envelopes, 128 }, nil 129 } 130 131 // GetAutoResponse returns a PublishResponse. 132 func (b *PubSubAutoRespondBatch) GetAutoResponse(_ actor.Context) interface{} { 133 return &PublishResponse{ 134 Status: PublishStatus_Ok, 135 } 136 } 137 138 // GetMessages returns the message. 139 func (b *PubSubAutoRespondBatch) GetMessages() []interface{} { 140 var messages []interface{} 141 for _, envelope := range b.Envelopes { 142 messages = append(messages, envelope) 143 } 144 return messages 145 } 146 147 // Deserialize converts a PubSubAutoRespondBatchTransport to a PubSubAutoRespondBatch. 148 func (t *PubSubAutoRespondBatchTransport) Deserialize() (remote.RootSerializable, error) { 149 batch := &PubSubBatchTransport{ 150 TypeNames: t.TypeNames, 151 Envelopes: t.Envelopes, 152 } 153 rs, err := batch.Deserialize() 154 if err != nil { 155 return nil, err 156 } 157 158 return &PubSubAutoRespondBatch{ 159 Envelopes: rs.(*PubSubBatch).Envelopes, 160 }, nil 161 }