Skip to content

Commit e1d2fd8

Browse files
committed
fix(mps-sync-plugin): properly check connection state when having multiple connections
1 parent 49cf8f4 commit e1d2fd8

File tree

2 files changed

+46
-16
lines changed

2 files changed

+46
-16
lines changed

mps-sync-plugin3/src/main/kotlin/org/modelix/mps/sync3/AppLevelModelSyncService.kt

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,42 +25,42 @@ class AppLevelModelSyncService() : Disposable {
2525

2626
private val connections = LinkedHashMap<ModelServerConnectionProperties, ServerConnection>()
2727
private val coroutinesScope = CoroutineScope(Dispatchers.Default)
28-
private val connectionCheckingJob = coroutinesScope.launchLoop(
29-
BackoffStrategy(
30-
initialDelay = 3_000,
31-
maxDelay = 10_000,
32-
factor = 1.2,
33-
),
34-
) {
35-
for (connection in synchronized(connections) { connections.values.toList() }) {
36-
connection.checkConnection()
37-
}
38-
}
3928

4029
@Synchronized
4130
fun getConnections() = synchronized(connections) { connections.values.toList() }
4231

4332
@Synchronized
4433
fun getOrCreateConnection(properties: ModelServerConnectionProperties): ServerConnection {
45-
return synchronized(connections) { connections.getOrPut(properties) { ServerConnection(properties) } }
34+
return synchronized(connections) { connections.getOrPut(properties) { ServerConnection(properties, coroutinesScope) } }
4635
}
4736

4837
override fun dispose() {
4938
coroutinesScope.cancel("disposed")
39+
connections.values.forEach { it.dispose() }
5040
}
5141

52-
class ServerConnection(val properties: ModelServerConnectionProperties) {
42+
class ServerConnection(val properties: ModelServerConnectionProperties, val coroutinesScope: CoroutineScope) {
5343
private var client: ValueWithMutex<ModelClientV2?> = ValueWithMutex(null)
5444
private var connected: Boolean = false
45+
private var enabled: Boolean = true
46+
private var disposed: Boolean = false
5547
private val authRequestHandler = AsyncAuthRequestHandler()
5648
private var authConfig: IAuthConfig = IAuthConfig.oauth {
5749
clientId(properties.oauthClientId ?: "external-mps")
5850
properties.oauthClientSecret?.let { clientSecret(it) }
5951
authRequestHandler(authRequestHandler)
6052
properties.repositoryId?.let { repositoryId(it) }
6153
}
62-
54+
private val connectionCheckingJob = coroutinesScope.launchLoop(
55+
BackoffStrategy(
56+
initialDelay = 3_000,
57+
maxDelay = 10_000,
58+
factor = 1.2,
59+
),
60+
) { checkConnection() }
6361
suspend fun getClient(): IModelClientV2 {
62+
checkDisposed()
63+
check(enabled) { "disabled" }
6464
return client.getValue() ?: client.updateValue {
6565
it ?: ModelClientV2.builder()
6666
.url(properties.url)
@@ -72,6 +72,7 @@ class AppLevelModelSyncService() : Disposable {
7272
}
7373

7474
suspend fun checkConnection() {
75+
if (!enabled) return
7576
try {
7677
getClient().getServerId()
7778
connected = true
@@ -83,7 +84,24 @@ class AppLevelModelSyncService() : Disposable {
8384

8485
fun isConnected(): Boolean = connected
8586

87+
fun isEnabled() = enabled
88+
89+
fun setEnabled(enabled: Boolean) = if (enabled) enable() else disable()
90+
91+
fun enable() {
92+
checkDisposed()
93+
if (enabled) return
94+
enabled = true
95+
}
96+
97+
fun disable() {
98+
if (!enabled) return
99+
enabled = false
100+
disconnect()
101+
}
102+
86103
fun disconnect() {
104+
checkDisposed()
87105
authRequestHandler.clear()
88106
runBlocking {
89107
client.updateValue {
@@ -95,16 +113,28 @@ class AppLevelModelSyncService() : Disposable {
95113
}
96114

97115
fun setAuthorizationConfig(config: IAuthConfig) {
116+
checkDisposed()
98117
this.authConfig = config
99118
runBlocking { client.updateValue { null } }
100119
}
101120

102121
fun configureOAuth(body: OAuthConfigBuilder.() -> Unit) {
122+
checkDisposed()
103123
this.authConfig = OAuthConfigBuilder(this.authConfig as? OAuthConfig).apply(body).build()
104124
runBlocking { client.updateValue { null } }
105125
}
106126

107-
fun getPendingAuthRequest(): String? = authRequestHandler.getPendingRequest()
127+
fun getPendingAuthRequest(): String? {
128+
checkDisposed()
129+
return authRequestHandler.getPendingRequest()
130+
}
131+
132+
fun dispose() {
133+
disable()
134+
disposed = true
135+
}
136+
137+
private fun checkDisposed() = check(!disposed) { "disposed" }
108138
}
109139
}
110140

mps-sync-plugin3/src/main/kotlin/org/modelix/mps/sync3/ModelSyncService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ class ModelSyncService(val project: Project) :
264264
}
265265

266266
override fun deactivate() {
267-
connection.disconnect()
267+
connection.disable()
268268
}
269269

270270
override fun remove() {

0 commit comments

Comments
 (0)