Commit bc16d2ee authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 878bf8ca
...@@ -29,7 +29,11 @@ package neo ...@@ -29,7 +29,11 @@ package neo
// several messages and does not itself denote a separate message, its // several messages and does not itself denote a separate message, its
// definition is prefixed with `//neo:proto typeonly` comment. // definition is prefixed with `//neo:proto typeonly` comment.
// //
// XXX neo:proto answerto x? (btw just needs "answer" flag) // The order of message definitions is significant - messages are assigned
// message IDs in the same order they are defined.
//
// For compatibility with neo/py is a message should have its ID assigned with
// "answer" bit set its definition is prefixed with `//neo:proto answer` comment.
// TODO regroup messages definitions to stay more close to 1 communication topic // TODO regroup messages definitions to stay more close to 1 communication topic
// TODO document protocol itself better (who sends who what with which semantic) // TODO document protocol itself better (who sends who what with which semantic)
...@@ -60,7 +64,7 @@ const ( ...@@ -60,7 +64,7 @@ const (
MAX_PACKET_SIZE = 0x4000000 MAX_PACKET_SIZE = 0x4000000
RESPONSE_MASK = 0x8000 answerBit = 0x8000
) )
type ErrorCode uint32 type ErrorCode uint32
...@@ -192,7 +196,7 @@ type Msg interface { ...@@ -192,7 +196,7 @@ type Msg interface {
neoMsgDecode(data []byte) (nread int, err error) neoMsgDecode(data []byte) (nread int, err error)
} }
// FIXME not pkt //neo:proto typeonly
type Address struct { type Address struct {
Host string Host string
Port uint16 Port uint16
...@@ -303,7 +307,7 @@ type RequestIdentification struct { ...@@ -303,7 +307,7 @@ type RequestIdentification struct {
IdTimestamp float64 IdTimestamp float64
} }
// XXX -> ReplyIdentification? RequestIdentification.Answer somehow ? //neo:proto answer
type AcceptIdentification struct { type AcceptIdentification struct {
NodeType NodeType // XXX name NodeType NodeType // XXX name
MyUUID NodeUUID MyUUID NodeUUID
......
...@@ -168,6 +168,7 @@ func loadPkg(pkgPath string, sources ...string) *types.Package { ...@@ -168,6 +168,7 @@ func loadPkg(pkgPath string, sources ...string) *types.Package {
// `//neo:proto ...` annotations // `//neo:proto ...` annotations
type Annotation struct { type Annotation struct {
typeonly bool typeonly bool
answer bool
} }
// parse checks doc for specific comment annotations and, if present, loads them. // parse checks doc for specific comment annotations and, if present, loads them.
...@@ -188,16 +189,45 @@ func (a *Annotation) parse(doc *ast.CommentGroup) { ...@@ -188,16 +189,45 @@ func (a *Annotation) parse(doc *ast.CommentGroup) {
switch arg { switch arg {
case "typeonly": case "typeonly":
if a.typeonly { if a.typeonly {
log.Fatalf("%v: duplicate typeonly", cpos) log.Fatalf("%v: duplicate `typeonly`", cpos)
} }
a.typeonly = true a.typeonly = true
case "answer":
if a.answer {
log.Fatalf("%v: duplicate `answer`", cpos)
}
a.answer = true
default: default:
log.Fatalf("%v: unknown neo:proto directive %q", cpos, arg) log.Fatalf("%v: unknown neo:proto directive %q", cpos, arg)
} }
} }
} }
// MsgCode represents message code in symbolic form: `serial (| answerBit)?`
type MsgCode struct {
msgSerial int
answer bool
}
func (c MsgCode) String() string {
s := fmt.Sprintf("%d", c.msgSerial)
if c.answer {
s += " | answerBit"
}
return s
}
// sort MsgCode by serial
type BySerial []MsgCode
func (v BySerial) Less(i, j int) bool { return v[i].msgSerial < v[j].msgSerial }
func (v BySerial) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
func (v BySerial) Len() int { return len(v) }
// ----------------------------------------
func main() { func main() {
var err error var err error
...@@ -223,11 +253,11 @@ import ( ...@@ -223,11 +253,11 @@ import (
"lab.nexedi.com/kirr/neo/go/zodb" "lab.nexedi.com/kirr/neo/go/zodb"
)`) )`)
msgTypeRegistry := map[int]string{} // msgCode -> typename msgTypeRegistry := map[MsgCode]string{} // msgCode -> typename
// go over message types declaration and generate marshal code for them // go over message types declaration and generate marshal code for them
buf.emit("// messages marshalling\n") buf.emit("// messages marshalling\n")
msgCode := 0 msgSerial := 0
for _, decl := range f.Decls { for _, decl := range f.Decls {
// we look for types (which can be only under GenDecl) // we look for types (which can be only under GenDecl)
gendecl, ok := decl.(*ast.GenDecl) gendecl, ok := decl.(*ast.GenDecl)
...@@ -262,10 +292,17 @@ import ( ...@@ -262,10 +292,17 @@ import (
continue continue
} }
fmt.Fprintf(&buf, "// %d. %s\n\n", msgCode, typename) // generate code for this type to implement neo.Msg
msgCode := MsgCode{msgSerial, specAnnotation.answer}
fmt.Fprintf(&buf, "// %d. %s", msgSerial, typename)
if specAnnotation.answer {
fmt.Fprintf(&buf, " (answer)")
}
fmt.Fprintf(&buf, "\n\n")
buf.emit("func (*%s) neoMsgCode() uint16 {", typename) buf.emit("func (*%s) neoMsgCode() uint16 {", typename)
buf.emit("return %d", msgCode) buf.emit("return %s", msgCode)
buf.emit("}\n") buf.emit("}\n")
buf.WriteString(generateCodecCode(typespec, &sizer{})) buf.WriteString(generateCodecCode(typespec, &sizer{}))
...@@ -273,20 +310,20 @@ import ( ...@@ -273,20 +310,20 @@ import (
buf.WriteString(generateCodecCode(typespec, &decoder{})) buf.WriteString(generateCodecCode(typespec, &decoder{}))
msgTypeRegistry[msgCode] = typename msgTypeRegistry[msgCode] = typename
msgCode++ msgSerial++
} }
} }
// now generate message types registry // now generate message types registry
buf.emit("\n// registry of message types") buf.emit("\n// registry of message types")
buf.emit("var msgTypeRegistry = map[uint16]reflect.Type {") // XXX key -> MsgCode ? buf.emit("var msgTypeRegistry = map[uint16]reflect.Type {")
// ordered by msgCode // ordered by msgCode
msgCodeV := []int{} msgCodeV := []MsgCode{}
for msgCode := range msgTypeRegistry { for msgCode := range msgTypeRegistry {
msgCodeV = append(msgCodeV, msgCode) msgCodeV = append(msgCodeV, msgCode)
} }
sort.Ints(msgCodeV) sort.Sort(BySerial(msgCodeV))
for _, msgCode := range msgCodeV { for _, msgCode := range msgCodeV {
buf.emit("%v: reflect.TypeOf(%v{}),", msgCode, msgTypeRegistry[msgCode]) buf.emit("%v: reflect.TypeOf(%v{}),", msgCode, msgTypeRegistry[msgCode])
...@@ -545,8 +582,8 @@ type sizer struct { ...@@ -545,8 +582,8 @@ type sizer struct {
// encode<typ2>(data[n2:], path2) // encode<typ2>(data[n2:], path2)
// ... // ...
// //
// TODO encode have to care in neoMsgEncode to emit preambule such that bound // TODO encode have to care in neoMsgEncode to emit preamble such that bound
// checking is performed only once (currenty compiler emits many of them) // checking is performed only once (currently compiler emits many of them)
type encoder struct { type encoder struct {
commonCodeGen commonCodeGen
n int // current write position in data n int // current write position in data
...@@ -635,7 +672,7 @@ func (d *decoder) resetPos() { ...@@ -635,7 +672,7 @@ func (d *decoder) resetPos() {
// mark current place for insertion of overflow check code // mark current place for insertion of overflow check code
// //
// The check will be acutally inserted later. // The check will be actually inserted later.
// //
// later: because first we go forward in decode path scanning ahead as far as // later: because first we go forward in decode path scanning ahead as far as
// we can - until first seeing variable-size encoded something, and then - // we can - until first seeing variable-size encoded something, and then -
......
...@@ -123,10 +123,10 @@ overflow: ...@@ -123,10 +123,10 @@ overflow:
return 0, ErrDecodeOverflow return 0, ErrDecodeOverflow
} }
// 2. AcceptIdentification // 2. AcceptIdentification (answer)
func (*AcceptIdentification) neoMsgCode() uint16 { func (*AcceptIdentification) neoMsgCode() uint16 {
return 2 return 2 | answerBit
} }
func (p *AcceptIdentification) neoMsgEncodedLen() int { func (p *AcceptIdentification) neoMsgEncodedLen() int {
...@@ -3415,92 +3415,92 @@ func (p *NotifyReady) neoMsgDecode(data []byte) (int, error) { ...@@ -3415,92 +3415,92 @@ func (p *NotifyReady) neoMsgDecode(data []byte) (int, error) {
// registry of message types // registry of message types
var msgTypeRegistry = map[uint16]reflect.Type{ var msgTypeRegistry = map[uint16]reflect.Type{
0: reflect.TypeOf(Error{}), 0: reflect.TypeOf(Error{}),
1: reflect.TypeOf(RequestIdentification{}), 1: reflect.TypeOf(RequestIdentification{}),
2: reflect.TypeOf(AcceptIdentification{}), 2 | answerBit: reflect.TypeOf(AcceptIdentification{}),
3: reflect.TypeOf(Ping{}), 3: reflect.TypeOf(Ping{}),
4: reflect.TypeOf(CloseClient{}), 4: reflect.TypeOf(CloseClient{}),
5: reflect.TypeOf(PrimaryMaster{}), 5: reflect.TypeOf(PrimaryMaster{}),
6: reflect.TypeOf(AnswerPrimary{}), 6: reflect.TypeOf(AnswerPrimary{}),
7: reflect.TypeOf(NotPrimaryMaster{}), 7: reflect.TypeOf(NotPrimaryMaster{}),
8: reflect.TypeOf(Recovery{}), 8: reflect.TypeOf(Recovery{}),
9: reflect.TypeOf(AnswerRecovery{}), 9: reflect.TypeOf(AnswerRecovery{}),
10: reflect.TypeOf(LastIDs{}), 10: reflect.TypeOf(LastIDs{}),
11: reflect.TypeOf(AnswerLastIDs{}), 11: reflect.TypeOf(AnswerLastIDs{}),
12: reflect.TypeOf(AskPartitionTable{}), 12: reflect.TypeOf(AskPartitionTable{}),
13: reflect.TypeOf(AnswerPartitionTable{}), 13: reflect.TypeOf(AnswerPartitionTable{}),
14: reflect.TypeOf(NotifyPartitionTable{}), 14: reflect.TypeOf(NotifyPartitionTable{}),
15: reflect.TypeOf(NotifyPartitionChanges{}), 15: reflect.TypeOf(NotifyPartitionChanges{}),
16: reflect.TypeOf(StartOperation{}), 16: reflect.TypeOf(StartOperation{}),
17: reflect.TypeOf(StopOperation{}), 17: reflect.TypeOf(StopOperation{}),
18: reflect.TypeOf(UnfinishedTransactions{}), 18: reflect.TypeOf(UnfinishedTransactions{}),
19: reflect.TypeOf(AnswerUnfinishedTransactions{}), 19: reflect.TypeOf(AnswerUnfinishedTransactions{}),
20: reflect.TypeOf(LockedTransactions{}), 20: reflect.TypeOf(LockedTransactions{}),
21: reflect.TypeOf(AnswerLockedTransactions{}), 21: reflect.TypeOf(AnswerLockedTransactions{}),
22: reflect.TypeOf(FinalTID{}), 22: reflect.TypeOf(FinalTID{}),
23: reflect.TypeOf(AnswerFinalTID{}), 23: reflect.TypeOf(AnswerFinalTID{}),
24: reflect.TypeOf(ValidateTransaction{}), 24: reflect.TypeOf(ValidateTransaction{}),
25: reflect.TypeOf(BeginTransaction{}), 25: reflect.TypeOf(BeginTransaction{}),
26: reflect.TypeOf(AnswerBeginTransaction{}), 26: reflect.TypeOf(AnswerBeginTransaction{}),
27: reflect.TypeOf(FailedVote{}), 27: reflect.TypeOf(FailedVote{}),
28: reflect.TypeOf(FinishTransaction{}), 28: reflect.TypeOf(FinishTransaction{}),
29: reflect.TypeOf(AnswerFinishTransaction{}), 29: reflect.TypeOf(AnswerFinishTransaction{}),
30: reflect.TypeOf(NotifyTransactionFinished{}), 30: reflect.TypeOf(NotifyTransactionFinished{}),
31: reflect.TypeOf(LockInformation{}), 31: reflect.TypeOf(LockInformation{}),
32: reflect.TypeOf(AnswerLockInformation{}), 32: reflect.TypeOf(AnswerLockInformation{}),
33: reflect.TypeOf(InvalidateObjects{}), 33: reflect.TypeOf(InvalidateObjects{}),
34: reflect.TypeOf(UnlockInformation{}), 34: reflect.TypeOf(UnlockInformation{}),
35: reflect.TypeOf(GenerateOIDs{}), 35: reflect.TypeOf(GenerateOIDs{}),
36: reflect.TypeOf(AnswerGenerateOIDs{}), 36: reflect.TypeOf(AnswerGenerateOIDs{}),
37: reflect.TypeOf(Deadlock{}), 37: reflect.TypeOf(Deadlock{}),
38: reflect.TypeOf(RebaseTransaction{}), 38: reflect.TypeOf(RebaseTransaction{}),
39: reflect.TypeOf(AnswerRebaseTransaction{}), 39: reflect.TypeOf(AnswerRebaseTransaction{}),
40: reflect.TypeOf(RebaseObject{}), 40: reflect.TypeOf(RebaseObject{}),
41: reflect.TypeOf(AnswerRebaseObject{}), 41: reflect.TypeOf(AnswerRebaseObject{}),
42: reflect.TypeOf(StoreObject{}), 42: reflect.TypeOf(StoreObject{}),
43: reflect.TypeOf(AnswerStoreObject{}), 43: reflect.TypeOf(AnswerStoreObject{}),
44: reflect.TypeOf(AbortTransaction{}), 44: reflect.TypeOf(AbortTransaction{}),
45: reflect.TypeOf(StoreTransaction{}), 45: reflect.TypeOf(StoreTransaction{}),
46: reflect.TypeOf(VoteTransaction{}), 46: reflect.TypeOf(VoteTransaction{}),
47: reflect.TypeOf(GetObject{}), 47: reflect.TypeOf(GetObject{}),
48: reflect.TypeOf(AnswerGetObject{}), 48: reflect.TypeOf(AnswerGetObject{}),
49: reflect.TypeOf(TIDList{}), 49: reflect.TypeOf(TIDList{}),
50: reflect.TypeOf(AnswerTIDList{}), 50: reflect.TypeOf(AnswerTIDList{}),
51: reflect.TypeOf(TIDListFrom{}), 51: reflect.TypeOf(TIDListFrom{}),
52: reflect.TypeOf(AnswerTIDListFrom{}), 52: reflect.TypeOf(AnswerTIDListFrom{}),
53: reflect.TypeOf(TransactionInformation{}), 53: reflect.TypeOf(TransactionInformation{}),
54: reflect.TypeOf(AnswerTransactionInformation{}), 54: reflect.TypeOf(AnswerTransactionInformation{}),
55: reflect.TypeOf(ObjectHistory{}), 55: reflect.TypeOf(ObjectHistory{}),
56: reflect.TypeOf(AnswerObjectHistory{}), 56: reflect.TypeOf(AnswerObjectHistory{}),
57: reflect.TypeOf(PartitionList{}), 57: reflect.TypeOf(PartitionList{}),
58: reflect.TypeOf(AnswerPartitionList{}), 58: reflect.TypeOf(AnswerPartitionList{}),
59: reflect.TypeOf(NodeList{}), 59: reflect.TypeOf(NodeList{}),
60: reflect.TypeOf(AnswerNodeList{}), 60: reflect.TypeOf(AnswerNodeList{}),
61: reflect.TypeOf(SetNodeState{}), 61: reflect.TypeOf(SetNodeState{}),
62: reflect.TypeOf(AddPendingNodes{}), 62: reflect.TypeOf(AddPendingNodes{}),
63: reflect.TypeOf(TweakPartitionTable{}), 63: reflect.TypeOf(TweakPartitionTable{}),
64: reflect.TypeOf(NotifyNodeInformation{}), 64: reflect.TypeOf(NotifyNodeInformation{}),
65: reflect.TypeOf(NodeInformation{}), 65: reflect.TypeOf(NodeInformation{}),
66: reflect.TypeOf(SetClusterState{}), 66: reflect.TypeOf(SetClusterState{}),
67: reflect.TypeOf(repairFlags{}), 67: reflect.TypeOf(repairFlags{}),
68: reflect.TypeOf(Repair{}), 68: reflect.TypeOf(Repair{}),
69: reflect.TypeOf(RepairOne{}), 69: reflect.TypeOf(RepairOne{}),
70: reflect.TypeOf(NotifyClusterState{}), 70: reflect.TypeOf(NotifyClusterState{}),
71: reflect.TypeOf(AskClusterState{}), 71: reflect.TypeOf(AskClusterState{}),
72: reflect.TypeOf(AnswerClusterState{}), 72: reflect.TypeOf(AnswerClusterState{}),
73: reflect.TypeOf(ObjectUndoSerial{}), 73: reflect.TypeOf(ObjectUndoSerial{}),
74: reflect.TypeOf(AnswerObjectUndoSerial{}), 74: reflect.TypeOf(AnswerObjectUndoSerial{}),
75: reflect.TypeOf(CheckCurrentSerial{}), 75: reflect.TypeOf(CheckCurrentSerial{}),
76: reflect.TypeOf(Pack{}), 76: reflect.TypeOf(Pack{}),
77: reflect.TypeOf(AnswerPack{}), 77: reflect.TypeOf(AnswerPack{}),
78: reflect.TypeOf(CheckReplicas{}), 78: reflect.TypeOf(CheckReplicas{}),
79: reflect.TypeOf(CheckPartition{}), 79: reflect.TypeOf(CheckPartition{}),
80: reflect.TypeOf(CheckTIDRange{}), 80: reflect.TypeOf(CheckTIDRange{}),
81: reflect.TypeOf(AnswerCheckTIDRange{}), 81: reflect.TypeOf(AnswerCheckTIDRange{}),
82: reflect.TypeOf(CheckSerialRange{}), 82: reflect.TypeOf(CheckSerialRange{}),
83: reflect.TypeOf(AnswerCheckSerialRange{}), 83: reflect.TypeOf(AnswerCheckSerialRange{}),
84: reflect.TypeOf(PartitionCorrupted{}), 84: reflect.TypeOf(PartitionCorrupted{}),
85: reflect.TypeOf(LastTransaction{}), 85: reflect.TypeOf(LastTransaction{}),
86: reflect.TypeOf(AnswerLastTransaction{}), 86: reflect.TypeOf(AnswerLastTransaction{}),
87: reflect.TypeOf(NotifyReady{}), 87: reflect.TypeOf(NotifyReady{}),
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment