mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-175943 - Migrate databases to EEL
GitOrigin-RevId: 5beea7d67c2777ecdedb62563935314c2a48bcff
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3d1cc196a5
commit
d09c7efa6a
@@ -418,4 +418,5 @@ separator.TableViewColoring.mode=Table Color Mapping
|
||||
separator.TableViewColoring.options=Options
|
||||
button.copy=Copy
|
||||
separator.order.by=ORDER BY
|
||||
separator.add.to.order.by=Add to ORDER BY
|
||||
separator.add.to.order.by=Add to ORDER BY
|
||||
driver.expert.properties.use.eel=Use EEL
|
||||
@@ -821,7 +821,6 @@ a:com.intellij.execution.rmi.RemoteProcessSupport
|
||||
- p:logText(java.lang.Object,com.intellij.execution.process.ProcessEvent,com.intellij.openapi.util.Key):V
|
||||
- p:onCreated(java.lang.Object,java.lang.Object,java.lang.Object):V
|
||||
- p:onProcessTerminated(com.intellij.execution.process.ProcessEvent):V
|
||||
- p:publishPort(I):I
|
||||
- release(java.lang.Object,java.lang.Object):java.util.concurrent.Future
|
||||
- p:sendDataAfterStart(com.intellij.execution.process.ProcessHandler):V
|
||||
- stopAll():V
|
||||
|
||||
@@ -182,6 +182,8 @@ com.intellij.execution.filters.Filter
|
||||
- com.intellij.openapi.project.PossiblyDumbAware
|
||||
- sf:EMPTY_ARRAY:com.intellij.execution.filters.Filter[]
|
||||
- a:applyFilter(java.lang.String,I):com.intellij.execution.filters.Filter$Result
|
||||
a:com.intellij.execution.rmi.RemoteProcessSupport
|
||||
- p:publishPort(I,java.lang.Object):I
|
||||
com.intellij.execution.runners.ProcessProxy
|
||||
- a:attach(com.intellij.execution.process.ProcessHandler):V
|
||||
- canSendBreak():Z
|
||||
|
||||
@@ -221,7 +221,7 @@ public abstract class RemoteProcessSupport<Target, EntryPoint, Parameters> {
|
||||
}
|
||||
}
|
||||
|
||||
protected int publishPort(int port) {
|
||||
protected int publishPort(int port, @NotNull Target target) {
|
||||
return port;
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ public abstract class RemoteProcessSupport<Target, EntryPoint, Parameters> {
|
||||
String id = data.get(2);
|
||||
String host = getRemoteHost();
|
||||
LOG.info("Started remote process on: " + host + ":" + port + "with service port " + servicesPort + " and id = " + id);
|
||||
result = new RunningInfo(info.handler, host, publishPort(port), id, publishPort(servicesPort));
|
||||
result = new RunningInfo(info.handler, host, publishPort(port, key.first), id, publishPort(servicesPort, key.first));
|
||||
myProcMap.put(key, result);
|
||||
myProcMap.notifyAll();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
<activityTracker implementation="com.intellij.util.MergingUpdateQueueActivityTracker"/>
|
||||
<applicationService serviceInterface="com.intellij.util.ui.update.MergingUpdateQueueTracker"
|
||||
serviceImplementation="com.intellij.util.MergingUpdateQueueTrackerImpl"/>
|
||||
<applicationService serviceInterface="com.intellij.util.download.eel.EelDownloadableFileService"
|
||||
serviceImplementation="com.intellij.util.download.impl.eel.EelDownloadableFileServiceImpl"/>
|
||||
<applicationService serviceInterface="com.intellij.util.download.DownloadableFileService"
|
||||
serviceImplementation="com.intellij.util.download.impl.DownloadableFileServiceImpl"/>
|
||||
<applicationService serviceInterface="com.intellij.notification.NotificationGroupManager"
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.util.download.impl.eel
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import com.intellij.util.download.DownloadableFileDescription
|
||||
import com.intellij.util.download.DownloadableFileSetDescription
|
||||
import com.intellij.util.download.eel.EelDownloadableFileService
|
||||
import com.intellij.util.download.eel.EelFileDownloader
|
||||
import com.intellij.util.download.impl.DownloadableFileDescriptionImpl
|
||||
|
||||
internal class EelDownloadableFileServiceImpl : EelDownloadableFileService() {
|
||||
|
||||
override fun createDownloader(description: DownloadableFileSetDescription): EelFileDownloader {
|
||||
return EelFileDownloaderImpl(description.getFiles())
|
||||
}
|
||||
|
||||
override fun createFileDescription(downloadUrl: String, fileName: String): DownloadableFileDescription {
|
||||
return DownloadableFileDescriptionImpl(downloadUrl, FileUtilRt.getNameWithoutExtension(fileName), FileUtilRt.getExtension(fileName))
|
||||
}
|
||||
}
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.util.download.impl.eel
|
||||
|
||||
import com.intellij.ide.IdeCoreBundle
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.progress.*
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.*
|
||||
import com.intellij.util.concurrency.AppExecutorUtil
|
||||
import com.intellij.util.download.DownloadableFileDescription
|
||||
import com.intellij.util.download.eel.EelFileDownloader
|
||||
import com.intellij.util.io.HttpRequests
|
||||
import com.intellij.util.io.delete
|
||||
import com.intellij.util.progress.ConcurrentTasksProgressManager
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.io.IOException
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.StandardCopyOption
|
||||
import java.util.*
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.ExecutionException
|
||||
import java.util.concurrent.Future
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
@ApiStatus.Internal
|
||||
internal class EelFileDownloaderImpl(
|
||||
private val myFileDescriptions: MutableList<out DownloadableFileDescription>,
|
||||
) : EelFileDownloader {
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun download(targetDir: Path): MutableList<Pair<Path, DownloadableFileDescription>> {
|
||||
val downloadedFiles = Collections.synchronizedList(mutableListOf<Pair<Path, DownloadableFileDescription>>())
|
||||
val existingFiles = Collections.synchronizedList(mutableListOf<Pair<Path, DownloadableFileDescription>>())
|
||||
|
||||
try {
|
||||
val progressManager = ConcurrentTasksProgressManager(createIndicator(), myFileDescriptions.size)
|
||||
val maxParallelDownloads = Runtime.getRuntime().availableProcessors()
|
||||
LOG.debug("Downloading ${myFileDescriptions.size} files using ${maxParallelDownloads} threads")
|
||||
val start = System.currentTimeMillis()
|
||||
val executor = AppExecutorUtil.createBoundedApplicationPoolExecutor("EelFileDownloaderImpl Pool", maxParallelDownloads)
|
||||
val results: MutableList<Future<Void>> = mutableListOf()
|
||||
val totalSize = AtomicLong()
|
||||
myFileDescriptions.forEach {
|
||||
results.add(executor.submit(createDownloadTask(progressManager, targetDir, it, existingFiles, downloadedFiles, totalSize)))
|
||||
}
|
||||
|
||||
results.forEach { it.getCatching() }
|
||||
val duration = System.currentTimeMillis() - start
|
||||
LOG.debug("Downloaded ${StringUtil.formatFileSize(totalSize.get())} in ${StringUtil.formatDuration(duration)}(${duration}ms)")
|
||||
|
||||
return (moveToDir(downloadedFiles, targetDir) + existingFiles).toMutableList()
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
deleteFiles(downloadedFiles)
|
||||
throw e
|
||||
}
|
||||
catch (e: IOException) {
|
||||
deleteFiles(downloadedFiles)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
private fun createDownloadTask(progressManager: ConcurrentTasksProgressManager,
|
||||
targetDir: Path, description: DownloadableFileDescription,
|
||||
existingFiles: MutableCollection<Pair<Path, DownloadableFileDescription>>,
|
||||
downloadedFiles: MutableCollection<Pair<Path, DownloadableFileDescription>>,
|
||||
totalSize: AtomicLong): Callable<Void> {
|
||||
return Callable {
|
||||
val indicator = progressManager.createSubTaskIndicator(1)
|
||||
indicator.checkCanceled()
|
||||
|
||||
val existing = targetDir.resolve(description.getDefaultFileName())
|
||||
val url = description.getDownloadUrl()
|
||||
if (url.startsWith(LIB_SCHEMA)) {
|
||||
val path = Path.of(url.removePrefix(LIB_SCHEMA))
|
||||
val file = PathManager.getLibDir().resolve(path)
|
||||
existingFiles.add(file to description)
|
||||
}
|
||||
else if (url.startsWith(LocalFileSystem.PROTOCOL_PREFIX)) {
|
||||
val path = Path.of(url.removePrefix(LocalFileSystem.PROTOCOL_PREFIX))
|
||||
if (Files.exists(path)) {
|
||||
existingFiles.add(path to description)
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.debug("Downloading `$url` into `$existing`")
|
||||
val downloaded: Path
|
||||
try {
|
||||
downloaded = downloadFile(description, existing, indicator)
|
||||
}
|
||||
catch (e: IOException) {
|
||||
throw IOException(IdeCoreBundle.message("error.file.download.failed", description.getDownloadUrl(),
|
||||
e.message), e)
|
||||
}
|
||||
if (downloaded == existing) {
|
||||
existingFiles.add(existing to description)
|
||||
}
|
||||
else {
|
||||
totalSize.addAndGet(Files.size(downloaded))
|
||||
downloadedFiles.add(downloaded to description)
|
||||
}
|
||||
}
|
||||
indicator.finished()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createIndicator(): ProgressIndicator {
|
||||
val indicator = ProgressManager.getInstance().getProgressIndicator()?.also { it.setIndeterminate(false) } ?: EmptyProgressIndicator()
|
||||
indicator.setText(IdeCoreBundle.message("progress.downloading.0.files.text", myFileDescriptions.size))
|
||||
|
||||
return indicator
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(EelFileDownloaderImpl::class.java)
|
||||
private const val LIB_SCHEMA = "lib://"
|
||||
|
||||
private fun Future<Void>.getCatching() {
|
||||
try {
|
||||
this.get()
|
||||
}
|
||||
catch (_: InterruptedException) {
|
||||
throw ProcessCanceledException()
|
||||
}
|
||||
catch (e: ExecutionException) {
|
||||
if (e.cause is IOException) {
|
||||
throw (e.cause as IOException)
|
||||
}
|
||||
if (e.cause is ProcessCanceledException) {
|
||||
throw (e.cause as ProcessCanceledException)
|
||||
}
|
||||
LOG.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun moveToDir(
|
||||
downloadedFiles: List<Pair<Path, DownloadableFileDescription>>,
|
||||
targetDir: Path
|
||||
): List<Pair<Path, DownloadableFileDescription>> {
|
||||
Files.createDirectories(targetDir)
|
||||
|
||||
return downloadedFiles.map { (fromPath, description) ->
|
||||
val fileName = description.generateFileName { name ->
|
||||
!Files.exists(targetDir.resolve(name))
|
||||
}
|
||||
|
||||
val toPath = targetDir.resolve(fileName)
|
||||
Files.move(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING)
|
||||
|
||||
toPath to description
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteFiles(pairs: List<Pair<Path, DownloadableFileDescription>>) = pairs.forEach { it.first.delete() }
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun downloadFile(
|
||||
description: DownloadableFileDescription,
|
||||
existingFile: Path,
|
||||
indicator: ProgressIndicator,
|
||||
): Path {
|
||||
val presentableUrl = description.getPresentableDownloadUrl()
|
||||
indicator.setText(IdeCoreBundle.message("progress.connecting.to.download.file.text", presentableUrl))
|
||||
|
||||
return HttpRequests.request(description.getDownloadUrl()).connect(object : HttpRequests.RequestProcessor<Path> {
|
||||
@Throws(IOException::class)
|
||||
override fun process(request: HttpRequests.Request): Path {
|
||||
val size = request.getConnection().getContentLength()
|
||||
if (Files.exists(existingFile) && size.toLong() == Files.size(existingFile)) {
|
||||
return existingFile
|
||||
}
|
||||
|
||||
indicator.setText(IdeCoreBundle.message("progress.download.file.text", description.getPresentableFileName(), presentableUrl))
|
||||
return request.saveToFile(Files.createTempFile("download.", ".tmp"), indicator)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.util.download.eel
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.util.download.DownloadableFileDescription
|
||||
import com.intellij.util.download.DownloadableFileSetDescription
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
abstract class EelDownloadableFileService {
|
||||
|
||||
abstract fun createDownloader(description: DownloadableFileSetDescription): EelFileDownloader
|
||||
|
||||
abstract fun createFileDescription(downloadUrl: String, fileName: String): DownloadableFileDescription
|
||||
|
||||
companion object {
|
||||
val instance: EelDownloadableFileService
|
||||
get() = ApplicationManager.getApplication().getService<EelDownloadableFileService>(EelDownloadableFileService::class.java)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.util.download.eel
|
||||
|
||||
import com.intellij.util.download.DownloadableFileDescription
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.io.IOException
|
||||
import java.nio.file.Path
|
||||
|
||||
/**
|
||||
* Use [EelDownloadableFileService] to create instances of this interface
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
interface EelFileDownloader {
|
||||
|
||||
/**
|
||||
* Download files synchronously. Call this method under progress only (see [com.intellij.openapi.progress.Task]).
|
||||
*
|
||||
* @param targetDir target directory for downloaded files
|
||||
* @return list of downloaded files with their descriptions
|
||||
* @throws IOException On errors.
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
fun download(targetDir: Path): MutableList<Pair<Path, DownloadableFileDescription>>
|
||||
}
|
||||
+1
-1
@@ -73,7 +73,7 @@ class EelMavenServerRemoteProcessSupport(
|
||||
}
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
override fun publishPort(port: Int): Int {
|
||||
override fun publishPort(port: Int, target: Any): Int {
|
||||
myProject.service<CoroutineService>().coroutineScope.launch {
|
||||
forwardLocalPort(eel.tunnels, port, EelTunnelsApi.HostAddress.Builder(port.toUShort()).hostname(remoteHost).build())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user