Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/net/ClientStream.hpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2018, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#ifndef CLIENT_STREAM_H
24
#define CLIENT_STREAM_H
25
26
#include "compile/CompilationTypes.hpp"
27
#include "ilgen/J9IlGeneratorMethodDetails.hpp"
28
#include "net/RawTypeConvert.hpp"
29
#include "net/CommunicationStream.hpp"
30
31
class SSLOutputStream;
32
class SSLInputStream;
33
34
namespace JITServer
35
{
36
enum VersionCheckStatus
37
{
38
NOT_DONE = 0,
39
PASSED = 1,
40
};
41
42
/**
43
@class ClientStream
44
@brief Implementation of the communication API for a client asking for remote JIT compilations
45
46
Typical sequence executed by a client is:
47
(1) Establish a connection to the JITServer by creating a ClientStream object
48
client = new (PERSISTENT_NEW) JITServer::ClientStream(compInfo->getPersistentInfo());
49
(2) Determine compilation parameters and send the compilation request over the network
50
client->buildCompileRequest(method, clazz, .................);
51
(3) Handle any queries from the server
52
Typical seq: (3.1) client->read(); (3.2) client->getRecvData(...); (3.3) client->write(...);
53
while(!handleServerMessage(client, frontend));
54
(4) Read compilation result
55
auto recv = client->getRecvData<uint32_t, std::string, std::string, .......>();
56
(5) install compiled code into code cache
57
*/
58
class ClientStream : public CommunicationStream
59
{
60
public:
61
/**
62
@brief Function called to perform static initialization of ClientStream
63
64
This is called during startup from rossa.cpp.
65
Creates SSL context, loads certificates and keys.
66
Only needs to be done once during JVM initialization.
67
68
Returns 0 if successful;; Otherwise, returns -1.
69
*/
70
static int static_init(TR::PersistentInfo *info);
71
72
explicit ClientStream(TR::PersistentInfo *info);
73
virtual ~ClientStream()
74
{
75
_numConnectionsClosed++;
76
}
77
78
/**
79
@brief Send a compilation request to the JITServer
80
81
As a side-effect, this function may also embed version information in the message
82
if this is the first message sent after a connection request.
83
*/
84
template <typename... T>
85
void buildCompileRequest(T... args)
86
{
87
if (getVersionCheckStatus() == NOT_DONE)
88
{
89
_cMsg.setFullVersion(getJITServerVersion(), CONFIGURATION_FLAGS);
90
write(MessageType::compilationRequest, args...);
91
_cMsg.clearFullVersion();
92
}
93
else // getVersionCheckStatus() == PASSED
94
{
95
_cMsg.clearFullVersion(); // the compatibility check is done. We clear the version to save message size.
96
write(MessageType::compilationRequest, args...);
97
}
98
}
99
100
/**
101
@brief Send a message to the JITServer
102
103
@param [in] type Message type
104
@param [in] args Additional arguments sent to the JITServer
105
*/
106
template <typename ...T>
107
void write(MessageType type, T... args)
108
{
109
_cMsg.setType(type);
110
setArgsRaw<T...>(_cMsg, args...);
111
112
writeMessage(_cMsg);
113
}
114
115
/**
116
@brief Read a message from the server
117
118
The read operation is blocking (subject to a timeout)
119
120
@return Returns the type of the message being received
121
*/
122
MessageType read()
123
{
124
readMessage(_sMsg);
125
return _sMsg.type();
126
}
127
128
/**
129
@brief Extract the data from the received message and return it
130
*/
131
template <typename ...T>
132
std::tuple<T...> getRecvData()
133
{
134
return getArgsRaw<T...>(_sMsg);
135
}
136
137
/**
138
@brief Send an error message to the JITServer
139
140
Examples of error messages include 'compilationInterrupted' (e.g. when class unloading happens),
141
'clientSessionTerminate' (e.g. when the client is about to exit),
142
and 'connectionTerminate' (e.g. when the client is closing the connection)
143
*/
144
template <typename ...T>
145
void writeError(MessageType type, T... args)
146
{
147
_cMsg.setType(type);
148
if (type == MessageType::compilationInterrupted || type == MessageType::connectionTerminate)
149
{
150
// _cMsg.clear();
151
}
152
else
153
setArgsRaw<T...>(_cMsg, args...);
154
writeMessage(_cMsg);
155
}
156
157
VersionCheckStatus getVersionCheckStatus()
158
{
159
return _versionCheckStatus;
160
}
161
162
void setVersionCheckStatus()
163
{
164
_versionCheckStatus = PASSED;
165
}
166
167
/**
168
@brief Function called when JITServer was discovered to be incompatible with the client
169
*/
170
static void incrementIncompatibilityCount(OMRPortLibrary *portLibrary)
171
{
172
OMRPORT_ACCESS_FROM_OMRPORT(portLibrary);
173
_incompatibilityCount += 1;
174
_incompatibleStartTime = omrtime_current_time_millis();
175
}
176
177
/**
178
@brief Function that answers whether JITServer is compatible with the client
179
180
Note that the discovery of the incompatibility is done in the first message
181
that the client sends to the server. This function is actually called to
182
determine if we need to try the compatibilty check again. The idea is that
183
the incompatible server could be killed and another one (compatible) could be
184
instantiated. If enough time has passed since the server was found to be
185
incompatible, then the client should try again. "Enough time" is defined as a
186
constant 10 second interval.
187
*/
188
static bool isServerCompatible(OMRPortLibrary *portLibrary)
189
{
190
OMRPORT_ACCESS_FROM_OMRPORT(portLibrary);
191
uint64_t current_time = omrtime_current_time_millis();
192
// the client periodically checks whether the server is compatible or not
193
// the retry interval is defined by RETRY_COMPATIBILITY_INTERVAL_MS
194
// we set _incompatibilityCount to 0 when it's time to retry for compatibility check
195
// otherwise, check if we exceed the number of incompatible connections
196
if ((current_time - _incompatibleStartTime) > RETRY_COMPATIBILITY_INTERVAL_MS)
197
_incompatibilityCount = 0;
198
199
return _incompatibilityCount < INCOMPATIBILITY_COUNT_LIMIT;
200
}
201
202
// Statistics
203
static int getNumConnectionsOpened() { return _numConnectionsOpened; }
204
static int getNumConnectionsClosed() { return _numConnectionsClosed; }
205
206
private:
207
static int _numConnectionsOpened;
208
static int _numConnectionsClosed;
209
VersionCheckStatus _versionCheckStatus; // indicates whether a version checking has been performed
210
static int _incompatibilityCount;
211
static uint64_t _incompatibleStartTime; // Time when version incomptibility has been detected
212
static const uint64_t RETRY_COMPATIBILITY_INTERVAL_MS; // (ms) When we should perform again a version compatibilty check
213
static const int INCOMPATIBILITY_COUNT_LIMIT;
214
215
static SSL_CTX *_sslCtx;
216
};
217
218
}
219
220
#endif // CLIENT_STREAM_H
221
222