-
Notifications
You must be signed in to change notification settings - Fork 0
/
conn_functions.go
252 lines (221 loc) · 8.59 KB
/
conn_functions.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
package bngsocket
import (
"errors"
"fmt"
"io"
"syscall"
)
// connIoEOFError wird bei einem IO EOF Socket Fehler ausgeführt.
// Diese Funktion behandelt das Auftreten eines EOF-Fehlers auf der Socket-Verbindung.
// Sie überprüft zunächst, ob die Verbindung bereits geschlossen wurde. Falls nicht, markiert
// sie die Verbindung als geschlossen und speichert den EOF-Fehler. Anschließend werden alle
// geöffneten Channel Listener, Channel Join Prozesse, offenen Channel Instanzen und ausgehenden
// RPC-Anfragen geschlossen oder verworfen. Abschließend wird eine Debug-Nachricht ausgegeben.
//
// Parameter:
// - socket *BngConn: Ein Zeiger auf das BngConn-Objekt, das die Socket-Verbindung und
// zugehörige Ressourcen verwaltet.
func connIoEOFError(socket *BngConn) {
// Es wird geprüft, ob die Verbindung bereits geschlossen wurde
if connectionIsClosed(socket) {
return
}
// Die Verbindung wird als geschlossen markiert
if socket.closed.Set(true) != 1 {
return
}
// Der Fehler wird zwischengespeichert
if socket.runningError.Set(io.EOF) != 1 {
return
}
// DEBUG: Verbindung wurde geschlossen
_DebugPrint("Connection closed")
// Alle Channel Listener werden geschlossen
for socket.openChannelListener.Count() != 0 {
// Das erste Item wird extrahiert
value, found := socket.openChannelListener.PopFirst()
if !found {
break
}
// Der Channel wird geschlossen
value.Close()
}
// Alle Channel Listener Anfragen werden geschlossen
for socket.openChannelJoinProcesses.Count() != 0 {
// Das erste Item wird extrahiert
value, found := socket.openChannelJoinProcesses.PopFirst()
if !found {
break
}
// Der Vorgang wird verworfen
close(value)
}
// Alle offenen Channel werden geschlossen
for socket.openChannelInstances.Count() != 0 {
// Das erste Item wird extrahiert
value, found := socket.openChannelInstances.PopFirst()
if !found {
break
}
// Der Channel wird geschlossen
value.Close()
}
// Alle ausgehenden RPC Anfragen werden geschlossen
for socket.openRpcRequests.Count() != 0 {
// Implementierung fehlt: Hier sollten die ausgehenden RPC Anfragen geschlossen werden
// Beispiel:
// rpcRequest, found := socket.openRpcRequests.PopFirst()
// if found {
// rpcRequest.Close()
// }
}
}
// readProcessErrorHandling wird verwendet, um beim Lesvorgang auf Fehler zu reagieren.
// Diese Funktion analysiert den aufgetretenen Fehler und führt entsprechende Maßnahmen durch.
// Bei einem EOF-Fehler wird connIoEOFError aufgerufen. Bei ECONNRESET oder EPIPE Fehlern wird
// die Methode consensusProtocolTermination mit einer entsprechenden Fehlermeldung aufgerufen.
// Für alle anderen Fehler wird ebenfalls consensusProtocolTermination aufgerufen.
// Die Funktion gibt einen booleschen Wert zurück, der angibt, ob die Verbindung geschlossen wurde.
//
// Parameter:
// - socket *BngConn: Ein Zeiger auf das BngConn-Objekt, das die Socket-Verbindung und
// zugehörige Ressourcen verwaltet.
// - err error: Der aufgetretene Fehler, der verarbeitet werden soll.
//
// Rückgabe:
// - bool: true, wenn die Verbindung geschlossen wurde, andernfalls false.
func readProcessErrorHandling(socket *BngConn, err error) bool {
// Der Fehler wird ermittelt und entsprechende Maßnahmen werden ergriffen
if errors.Is(err, io.EOF) {
connIoEOFError(socket)
} else if errors.Is(err, syscall.ECONNRESET) {
consensusProtocolTermination(socket, fmt.Errorf("bngsocket->constantReading: "+err.Error()))
} else if errors.Is(err, syscall.EPIPE) {
consensusProtocolTermination(socket, fmt.Errorf("bngsocket->constantReading: "+err.Error()))
} else {
consensusProtocolTermination(socket, fmt.Errorf("bngsocket->constantReading: "+err.Error()))
}
return true
}
// writeProcessErrorHandling wird verwendet, um beim Schreibvorgang auf Fehler zu reagieren.
// Diese Funktion analysiert den aufgetretenen Fehler und führt entsprechende Maßnahmen durch.
// Bei einem EOF-Fehler wird connIoEOFError aufgerufen. Bei ECONNRESET oder EPIPE Fehlern wird
// die Methode consensusProtocolTermination mit einer entsprechenden Fehlermeldung aufgerufen.
// Für alle anderen Fehler wird ebenfalls consensusProtocolTermination aufgerufen.
//
// Parameter:
// - socket *BngConn: Ein Zeiger auf das BngConn-Objekt, das die Socket-Verbindung und
// zugehörige Ressourcen verwaltet.
// - err error: Der aufgetretene Fehler, der verarbeitet werden soll.
//
// Rückgabe:
// - bool: true, wenn die Verbindung geschlossen wurde, andernfalls false.
func writeProcessErrorHandling(socket *BngConn, err error) bool {
// Der Fehler wird ermittelt und entsprechende Maßnahmen werden ergriffen
if errors.Is(err, io.EOF) {
connIoEOFError(socket)
} else if errors.Is(err, syscall.ECONNRESET) {
consensusProtocolTermination(socket, fmt.Errorf("bngsocket->constantWriting: "+err.Error()))
} else if errors.Is(err, syscall.EPIPE) {
consensusProtocolTermination(socket, fmt.Errorf("bngsocket->constantWriting: "+err.Error()))
} else {
consensusProtocolTermination(socket, fmt.Errorf("bngsocket->constantWriting: "+err.Error()))
}
return true
}
// runningBackgroundServingLoop gibt an, ob die Hintergrund-Dauerschleifen eines Sockets aktiv sein sollen.
// Diese Funktion überprüft, ob die Verbindung des gegebenen BngConn-Objekts geschlossen wurde. Wenn die
// Verbindung nicht geschlossen ist, sollen die Hintergrund-Dauerschleifen weiterhin laufen.
//
// Parameter:
// - ipcc *BngConn: Ein Zeiger auf das BngConn-Objekt, das die Socket-Verbindung und zugehörige
// Ressourcen verwaltet.
//
// Rückgabe:
// - bool: true, wenn die Hintergrund-Dauerschleifen weiterhin laufen sollen, ansonsten false.
func runningBackgroundServingLoop(ipcc *BngConn) bool {
return !connectionIsClosed(ipcc)
}
// connectionIsClosed gibt an, ob eine Verbindung geschlossen wurde.
// Diese Funktion prüft verschiedene Zustände des BngConn-Objekts, um festzustellen, ob die Verbindung
// bereits geschlossen ist oder ein Fehler aufgetreten ist, der die Verbindung beendet hat.
//
// Parameter:
// - ipcc *BngConn: Ein Zeiger auf das BngConn-Objekt, das die Socket-Verbindung und zugehörige
// Ressourcen verwaltet.
//
// Rückgabe:
// - bool: true, wenn die Verbindung geschlossen wurde, ansonsten false.
func connectionIsClosed(ipcc *BngConn) bool {
if ipcc.closed.Get() {
return true
}
if ipcc.closing.Get() {
return true
}
if ipcc.runningError.Get() != nil {
return true
}
return false
}
// fullCloseConn wird verwendet, um den Socket vollständig zu schließen.
// Diese Funktion sorgt dafür, dass die Verbindung ordnungsgemäß geschlossen wird, indem sie
// verschiedene Schritte durchführt, um sicherzustellen, dass alle Ressourcen freigegeben werden.
// Sie markiert die Verbindung als geschlossen, schließt den Socket, wartet auf den Abschluss aller
// Hintergrundprozesse und setzt das geschlossene Flag. Bei Fehlern während des Schließvorgangs
// wird der Fehler zurückgegeben.
//
// Parameter:
// - s *BngConn: Ein Zeiger auf das BngConn-Objekt, das die Socket-Verbindung und zugehörige
// Ressourcen verwaltet.
//
// Rückgabe:
// - error: Ein Fehler, falls beim Schließen der Verbindung ein Problem aufgetreten ist, ansonsten nil.s
func fullCloseConn(s *BngConn) error {
if connectionIsClosed(s) {
return io.EOF
}
// DEBUG
defer _DebugPrint("Connection closed")
// Es wird Markiert dass der Socket geschlossen ist
s.closing.Set(true)
// Der Socket wird geschlossen
s.connMutex.Lock()
closeerr := s.conn.Close()
s.connMutex.Unlock()
// LOG
_DebugPrint(fmt.Sprintf("BngConn(%s): CLOSE FULL", s._innerhid))
// Es wird gewartet dass alle Hintergrundaufgaben abgeschlossen werden
s.backgroundProcesses.Wait()
// Es wird Signalisiert, dass die Verbindung final geschlossen wurde
s.closed.Set(true)
// Sollte ein Fehler vorhanden sein, wird dieser Zurückgegeben
if closeerr != nil {
fmt.Println("AA: " + closeerr.Error())
return closeerr
}
// Es ist kein Fehler aufgetreten
return nil
}
// Wird verwendet wenn ein Abweichender Protokoll Fehler auftritt
func consensusProtocolTermination(o *BngConn, reason error) {
// Es wird geprüft ob die Verbindung bereits geschlossen wurde, wenn ja, wird der Vorgang verworfen
if connectionIsClosed(o) {
return
}
// LOG
_DebugPrint(fmt.Sprintf("BngConn(%s): ERROR %s", o._innerhid, reason.Error()))
// Der connMutextex wird angewenet
o.connMutex.Lock()
defer o.connMutex.Unlock()
// Der Fehler wird geschrieben
if reason == nil {
o.runningError.Set(fmt.Errorf(""))
} else {
o.runningError.Set(reason)
}
// Es wird Signalisiert dass die Verbindung geschlossen wurde
o.closed.Set(true)
// Die Socket Verbindung wird geschlossen
o.conn.Close()
}