From 9127ead853ec6e844877826e56d0f08513f2e1ef Mon Sep 17 00:00:00 2001 From: Kirill Starkov Date: Mon, 6 May 2024 15:19:49 +0800 Subject: [PATCH] fix incorrect usage stats https://github.com/smallcloudai/refact-intellij/issues/136 --- .github/workflows/release.yml | 30 +++++++++++++++++++ .../smallcloud/refactai/account/LoginUser.kt | 16 +++++----- .../smallcloud/refactai/io/AsyncConnection.kt | 2 +- .../smallcloud/refactai/io/RequestHelpers.kt | 10 +++---- .../refactai/listeners/UninstallListener.kt | 2 +- .../refactai/lsp/LSPProcessHolder.kt | 8 +++-- .../modes/completion/CompletionMode.kt | 2 +- .../refactai/panes/gptchat/ChatGPTProvider.kt | 2 +- .../refactai/statistic/UsageStats.kt | 6 ++-- 9 files changed, 55 insertions(+), 23 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c6fa9bb1..736636c5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,12 +45,15 @@ jobs: GIT_BRANCH=${raw##*/} if [[ ${GIT_BRANCH} == "main" ]]; then echo "PUBLISH_CHANNEL=default" >> "$GITHUB_ENV" + echo "slack_notification_channel=stable" >> "$GITHUB_OUTPUT" echo "PUBLISH_EAP=0" >> "$GITHUB_ENV" else echo "PUBLISH_CHANNEL=eap" >> "$GITHUB_ENV" + echo "slack_notification_channel=eap" >> "$GITHUB_OUTPUT" echo "PUBLISH_EAP=1" >> "$GITHUB_ENV" fi echo "GIT_BRANCH=${GIT_BRANCH}" >> "$GITHUB_ENV" + echo "plugin_version=$(./gradlew properties -q | awk '/^version:/ {print $2}')" >> $GITHUB_OUTPUT echo "lsp_version=$(cat refact_lsp)" >> $GITHUB_OUTPUT - uses: convictional/trigger-workflow-and-wait@v1.6.1 @@ -151,3 +154,30 @@ jobs: PRIVATE_KEY_PASSWORD: ${{ secrets.PRIVATE_KEY_PASSWORD }} run: ./gradlew publishPlugin + - name: Post to a Slack channel + id: slack + uses: slackapi/slack-github-action@v1.26.0 + with: + payload: | + { + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "JB plugin ${{ steps.setupvars.outputs.plugin_version }} is released in ${{ steps.setupvars.outputs.slack_notification_channel }} channel", + "emoji": true + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "by ${{ github.actor }}" + } + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK diff --git a/src/main/kotlin/com/smallcloud/refactai/account/LoginUser.kt b/src/main/kotlin/com/smallcloud/refactai/account/LoginUser.kt index c28340f4..c0c38a06 100644 --- a/src/main/kotlin/com/smallcloud/refactai/account/LoginUser.kt +++ b/src/main/kotlin/com/smallcloud/refactai/account/LoginUser.kt @@ -68,7 +68,7 @@ private fun tryTicketPass(): String? { AccountManager.apiKey = body.get("secret_key").asString AccountManager.ticket = null InferenceGlobalContext.status = ConnectionStatus.CONNECTED - UsageStats.addStatistic(true, UsageStatistic("recall"), defaultRecallUrl.toString(), "") + UsageStats?.addStatistic(true, UsageStatistic("recall"), defaultRecallUrl.toString(), "") finishedGood() return null } else if (retcode == "FAILED" && humanReadableMessage.contains("rate limit")) { @@ -76,14 +76,14 @@ private fun tryTicketPass(): String? { return "OK" } else { result.body?.let { - UsageStats.addStatistic(false, UsageStatistic("recall (1)"), defaultRecallUrl.toString(), it) + UsageStats?.addStatistic(false, UsageStatistic("recall (1)"), defaultRecallUrl.toString(), it) logError("recall", it) } return "" } } catch (e: Exception) { - UsageStats.addStatistic(false, UsageStatistic("recall (2)"), defaultRecallUrl.toString(), e) + UsageStats?.addStatistic(false, UsageStatistic("recall (2)"), defaultRecallUrl.toString(), e) e.message?.let { logError("recall", it) } return "" } @@ -143,29 +143,29 @@ private fun tryLoginWithApiKey(): String { InferenceGlobalContext.isNewChatStyle = (body.get("chat-v1-style").asInt > 0) } - UsageStats.addStatistic(true, UsageStatistic("login"), url.toString(), "") + UsageStats?.addStatistic(true, UsageStatistic("login"), url.toString(), "") finishedGood() return "OK" } else if (retcode == "FAILED" && humanReadableMessage.contains("rate limit")) { logError("login-failed", humanReadableMessage, false) - UsageStats.addStatistic(false, UsageStatistic("login-failed"), url.toString(), humanReadableMessage) + UsageStats?.addStatistic(false, UsageStatistic("login-failed"), url.toString(), humanReadableMessage) return "OK" } else if (retcode == "FAILED") { AccountManager.user = null AccountManager.activePlan = null logError("login-failed", humanReadableMessage) - UsageStats.addStatistic(false, UsageStatistic("login-failed"), url.toString(), humanReadableMessage) + UsageStats?.addStatistic(false, UsageStatistic("login-failed"), url.toString(), humanReadableMessage) return "" } else { AccountManager.user = null AccountManager.activePlan = null logError("login-failed", "unrecognized response") - UsageStats.addStatistic(false, UsageStatistic("login (2)"), url.toString(), "unrecognized response") + UsageStats?.addStatistic(false, UsageStatistic("login (2)"), url.toString(), "unrecognized response") return "" } } catch (e: Exception) { e.message?.let { logError("login-fail", it) } - UsageStats.addStatistic(false, UsageStatistic("login (3)"), url.toString(), e) + UsageStats?.addStatistic(false, UsageStatistic("login (3)"), url.toString(), e) return "" } } diff --git a/src/main/kotlin/com/smallcloud/refactai/io/AsyncConnection.kt b/src/main/kotlin/com/smallcloud/refactai/io/AsyncConnection.kt index 1fb1375b..284179be 100644 --- a/src/main/kotlin/com/smallcloud/refactai/io/AsyncConnection.kt +++ b/src/main/kotlin/com/smallcloud/refactai/io/AsyncConnection.kt @@ -215,7 +215,7 @@ class AsyncConnection : Disposable { override fun failed(ex: java.lang.Exception?) { if (ex !is SMCExceptions) - UsageStats.addStatistic(false, stat, uri.toString(), ex.toString()) + UsageStats?.addStatistic(false, stat, uri.toString(), ex.toString()) if (ex is java.net.SocketException || ex is java.net.UnknownHostException) { InferenceGlobalContext.status = ConnectionStatus.DISCONNECTED diff --git a/src/main/kotlin/com/smallcloud/refactai/io/RequestHelpers.kt b/src/main/kotlin/com/smallcloud/refactai/io/RequestHelpers.kt index 643de73b..76f2be43 100644 --- a/src/main/kotlin/com/smallcloud/refactai/io/RequestHelpers.kt +++ b/src/main/kotlin/com/smallcloud/refactai/io/RequestHelpers.kt @@ -15,25 +15,25 @@ private fun lookForCommonErrors(json: JsonObject, request: SMCRequest): String? if (json.has("detail")) { val gson = Gson() val detail = gson.toJson(json.get("detail")) - UsageStats.addStatistic(false, request.stat, request.uri.toString(), detail) + UsageStats?.addStatistic(false, request.stat, request.uri.toString(), detail) return detail } if (json.has("retcode") && json.get("retcode").asString != "OK") { - UsageStats.addStatistic( + UsageStats?.addStatistic( false, request.stat, request.uri.toString(), json.get("human_readable_message").asString ) return json.get("human_readable_message").asString } if (json.has("status") && json.get("status").asString == "error") { - UsageStats.addStatistic( + UsageStats?.addStatistic( false, request.stat, request.uri.toString(), json.get("human_readable_message").asString ) return json.get("human_readable_message").asString } if (json.has("error")) { - UsageStats.addStatistic( + UsageStats?.addStatistic( false, request.stat, request.uri.toString(), json.get("error").asJsonObject.get("message").asString ) @@ -69,7 +69,7 @@ fun streamedInferenceFetch( val json = gson.fromJson(body, SMCStreamingPeace::class.java) InferenceGlobalContext.lastAutoModel = json.model json.requestId = reqId - UsageStats.addStatistic(true, request.stat, request.uri.toString(), "") + UsageStats?.addStatistic(true, request.stat, request.uri.toString(), "") dataReceived(json) }, errorDataReceived = { diff --git a/src/main/kotlin/com/smallcloud/refactai/listeners/UninstallListener.kt b/src/main/kotlin/com/smallcloud/refactai/listeners/UninstallListener.kt index 5f7f70bc..1fd1e680 100644 --- a/src/main/kotlin/com/smallcloud/refactai/listeners/UninstallListener.kt +++ b/src/main/kotlin/com/smallcloud/refactai/listeners/UninstallListener.kt @@ -22,7 +22,7 @@ class UninstallListener: PluginStateListener { if (Thread.currentThread().stackTrace.any { it.methodName == "uninstallAndUpdateUi" } && SINGLE_TIME_UNINSTALL == 0) { SINGLE_TIME_UNINSTALL++ - UsageStats.addStatistic(true, UsageStatistic("uninstall"), defaultCloudUrl.toString(), "") + UsageStats?.addStatistic(true, UsageStatistic("uninstall"), defaultCloudUrl.toString(), "") BrowserUtil.browse("https://refact.ai/feedback?ide=${Resources.client}&tenant=${AccountManager.user}") } } diff --git a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt index 52205fe9..79b97ced 100644 --- a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt +++ b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt @@ -9,7 +9,8 @@ import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project import com.intellij.openapi.util.SystemInfo -import com.intellij.openapi.util.io.FileUtil.* +import com.intellij.openapi.util.io.FileUtil.getTempDirectory +import com.intellij.openapi.util.io.FileUtil.setExecutable import com.intellij.util.concurrency.AppExecutorUtil import com.intellij.util.messages.MessageBus import com.intellij.util.messages.Topic @@ -198,8 +199,10 @@ class LSPProcessHolder(val project: Project): Disposable { } } process!!.onExit().thenAcceptAsync { process1 -> - logger.warn("LSP bad_things_happened " + + if (process1.exitValue() != 0) { + logger.warn("LSP bad_things_happened " + process1.inputStream.bufferedReader().use { it.readText() }) + } } attempt = 0 while (attempt < 5) { @@ -249,7 +252,6 @@ class LSPProcessHolder(val project: Project): Disposable { override fun dispose() { terminate() - delete(Path(BIN_PATH)) scheduler.shutdown() schedulerCaps.shutdown() } diff --git a/src/main/kotlin/com/smallcloud/refactai/modes/completion/CompletionMode.kt b/src/main/kotlin/com/smallcloud/refactai/modes/completion/CompletionMode.kt index c52038c2..8e4c2323 100644 --- a/src/main/kotlin/com/smallcloud/refactai/modes/completion/CompletionMode.kt +++ b/src/main/kotlin/com/smallcloud/refactai/modes/completion/CompletionMode.kt @@ -308,7 +308,7 @@ class CompletionMode( completionLayout?.apply { applyPreview(caret ?: editor.caretModel.currentCaret) lastCompletionData?.snippetTelemetryId?.let { - UsageStats.snippetAccepted(it) + UsageStats?.snippetAccepted(it) } dispose() } diff --git a/src/main/kotlin/com/smallcloud/refactai/panes/gptchat/ChatGPTProvider.kt b/src/main/kotlin/com/smallcloud/refactai/panes/gptchat/ChatGPTProvider.kt index b5febf85..ef629834 100644 --- a/src/main/kotlin/com/smallcloud/refactai/panes/gptchat/ChatGPTProvider.kt +++ b/src/main/kotlin/com/smallcloud/refactai/panes/gptchat/ChatGPTProvider.kt @@ -164,7 +164,7 @@ class ChatGPTProvider(val project: Project) : ActionListener { streamSchedulerTasks.add(streamScheduler.submit { pane.sendingState = ChatGPTPane.SendingState.READY }) - UsageStats.instance.addStatistic(true, stat, req.uri.toString(), "") + UsageStats.instance?.addStatistic(true, stat, req.uri.toString(), "") }, errorDataReceived = { ApplicationManager.getApplication().invokeLater { diff --git a/src/main/kotlin/com/smallcloud/refactai/statistic/UsageStats.kt b/src/main/kotlin/com/smallcloud/refactai/statistic/UsageStats.kt index dced81bd..5c0b59a3 100644 --- a/src/main/kotlin/com/smallcloud/refactai/statistic/UsageStats.kt +++ b/src/main/kotlin/com/smallcloud/refactai/statistic/UsageStats.kt @@ -6,11 +6,11 @@ import com.intellij.openapi.Disposable import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project -import com.intellij.openapi.project.ProjectManager import com.intellij.util.concurrency.AppExecutorUtil import com.smallcloud.refactai.Resources.defaultReportUrlSuffix import com.smallcloud.refactai.Resources.defaultSnippetAcceptedUrlSuffix import com.smallcloud.refactai.io.sendRequest +import com.smallcloud.refactai.listeners.LastEditorGetterListener.Companion.LAST_EDITOR import com.smallcloud.refactai.settings.AppSettingsState.Companion.acceptedCompletionCounter import com.smallcloud.refactai.lsp.LSPProcessHolder.Companion.getInstance as getLSPProcessHolder @@ -96,9 +96,9 @@ class UsageStats(private val project: Project): Disposable { companion object { @JvmStatic - val instance: UsageStats + val instance: UsageStats? get() { - val project = ProjectManager.getInstance().openProjects.first() + val project = LAST_EDITOR?.project?: return null return project.service() } }