11package com.intellij.lang.jsgraphql.schema.library
22
33import com.intellij.openapi.application.ApplicationManager
4+ import com.intellij.openapi.application.readAction
45import com.intellij.openapi.components.Service
56import com.intellij.openapi.components.service
67import com.intellij.openapi.components.serviceAsync
@@ -14,13 +15,11 @@ import com.intellij.platform.backend.workspace.toVirtualFileUrl
1415import com.intellij.platform.workspace.storage.MutableEntityStorage
1516import com.intellij.psi.search.GlobalSearchScope
1617import com.intellij.util.PathUtil
18+ import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
19+ import com.intellij.util.concurrency.annotations.RequiresReadLockAbsence
1720import com.intellij.util.io.URLUtil
18- import kotlinx.coroutines.CoroutineScope
19- import kotlinx.coroutines.future.asCompletableFuture
20- import kotlinx.coroutines.launch
21+ import org.jetbrains.annotations.ApiStatus
2122import org.jetbrains.annotations.TestOnly
22- import org.jetbrains.annotations.VisibleForTesting
23- import java.util.concurrent.CompletableFuture
2423import java.util.concurrent.ConcurrentHashMap
2524import kotlin.concurrent.Volatile
2625
@@ -35,8 +34,9 @@ private val BUNDLED_RESOURCE_PATHS = mapOf(
3534
3635private val BUNDLED_LIBRARIES_IDS = BUNDLED_RESOURCE_PATHS .keys.map { it.identifier }.toSet()
3736
37+ @ApiStatus.Experimental
3838@Service(Service .Level .PROJECT )
39- class GraphQLLibraryManager (private val project : Project , @VisibleForTesting val cs : CoroutineScope ) {
39+ class GraphQLLibraryManager (private val project : Project ) {
4040 companion object {
4141 private val LOG = logger<GraphQLLibraryManager >()
4242
@@ -57,18 +57,17 @@ class GraphQLLibraryManager(private val project: Project, @VisibleForTesting val
5757 shouldInitializeLibraries = enabled
5858 }
5959
60- private val isEnabled: Boolean
61- get() = ApplicationManager .getApplication().isUnitTestMode() && ! shouldInitializeLibraries
62-
6360 /* *
6461 * Registers an external GraphQL library.
6562 * If a library with the same identifier is already registered,
6663 * it will be replaced with the new library.
6764 *
6865 * @param library The external GraphQL library to register, containing its descriptor and set of root URLs.
6966 */
67+ @RequiresBackgroundThread
68+ @RequiresReadLockAbsence
7069 suspend fun registerExternalLibrary (library : GraphQLLibrary ) {
71- if (isEnabled ) {
70+ if (! shouldInitializeLibraries ) {
7271 return
7372 }
7473
@@ -81,16 +80,16 @@ class GraphQLLibraryManager(private val project: Project, @VisibleForTesting val
8180 attachLibrary(library)
8281 }
8382
84- private fun isBundledLibrary (library : GraphQLLibrary ): Boolean = library.descriptor.identifier in BUNDLED_LIBRARIES_IDS
85-
8683 /* *
8784 * If the specified library is not currently registered, a warning message is logged.
8885 * Otherwise, the library is removed from the list of external libraries and detached.
8986 *
9087 * @param library The external GraphQL library to unregister, containing its descriptor and set of root URLs.
9188 */
89+ @RequiresBackgroundThread
90+ @RequiresReadLockAbsence
9291 suspend fun unregisterExternalLibrary (library : GraphQLLibrary ) {
93- if (isEnabled ) {
92+ if (! shouldInitializeLibraries ) {
9493 return
9594 }
9695
@@ -115,31 +114,19 @@ class GraphQLLibraryManager(private val project: Project, @VisibleForTesting val
115114 * @see getOrCreateLibraries
116115 * @see updateLibrariesWorkspaceModel
117116 */
117+ @RequiresBackgroundThread
118+ @RequiresReadLockAbsence
118119 suspend fun syncLibraries () {
119- if (isEnabled ) {
120+ if (! shouldInitializeLibraries ) {
120121 return
121122 }
122123
123124 val libraries = getOrCreateLibraries().also { LOG .debug { " GraphQL libraries to sync:\n ${it.joinToString(" \n " )} " } }
124- val availableLibraries = libraries.filter { it.descriptor.isEnabled(project) }
125+ val availableLibraries = libraries.filter { readAction { it.descriptor.isEnabled(project) } }
125126 updateLibrariesWorkspaceModel(availableLibraries)
126127 }
127128
128- /* *
129- * Schedules the synchronization of GraphQL libraries in the workspace.
130- *
131- * This method triggers the [syncLibraries] function to execute asynchronously,
132- * ensuring that the libraries, both external and bundled, are synchronized and updated
133- * in the workspace model.
134- *
135- * The synchronization is managed using a CompletableFuture, allowing the Java code
136- * to monitor its completion or handle any exceptions.
137- *
138- * @return A [CompletableFuture] representing the asynchronous task of library synchronization.
139- */
140- fun scheduleLibrariesSynchronization (): CompletableFuture <Unit > {
141- return cs.launch { syncLibraries() }.asCompletableFuture()
142- }
129+ private fun isBundledLibrary (library : GraphQLLibrary ): Boolean = library.descriptor.identifier in BUNDLED_LIBRARIES_IDS
143130
144131 val libraries: Collection <GraphQLLibrary >
145132 get() = sequenceOf(bundledLibraries.values, externalLibraries.values)
0 commit comments