diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionSpanCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionSpanCE.java index 26b1091c60a0..13656b94a439 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionSpanCE.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ActionSpanCE.java @@ -22,6 +22,12 @@ public class ActionSpanCE { public static final String GET_ENVIRONMENT_ID = APPSMITH_SPAN_PREFIX + "getEnvironmentId"; public static final String POPULATED_EXECUTE_ACTION_DTO_MONO = APPSMITH_SPAN_PREFIX + "populatedExecuteActionDTOMono"; + + public static final String VALIDATE_AUTHENTICATION_DATASOURCE_STORAGE = + APPSMITH_SPAN_PREFIX + "validateAuthenticationDatasourceStorage"; + public static final String VERIFY_DATASOURCE_AND_MAKE_REQUEST = + APPSMITH_SPAN_PREFIX + "verifyDatasourceAndMakeRequest"; + public static final String SEND_EXECUTE_ANALYTICS_EVENT = APPSMITH_SPAN_PREFIX + "sendExecuteAnalyticsEvent"; public static final String POPULATE_AND_EXECUTE_ACTION = APPSMITH_SPAN_PREFIX + "populateAndExecuteAction"; public static final String GET_VALID_ACTION_FOR_EXECUTION = APPSMITH_SPAN_PREFIX + "getValidActionForExecution"; public static final String GET_CACHED_PLUGIN_FOR_ACTION_EXECUTION = diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java index 92d7e5848627..7f0dc2ecd3c3 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java @@ -68,6 +68,8 @@ import reactor.core.observability.micrometer.Micrometer; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; +import reactor.util.function.Tuple2; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -360,6 +362,7 @@ public Mono executeAction( : getCachedPluginForActionExecution(datasourceStorageMono) .name(GET_CACHED_PLUGIN_FOR_ACTION_EXECUTION) .tap(Micrometer.observation(observationRegistry)); + Mono pluginExecutorMono = pluginExecutorHelper .getPluginExecutor(pluginMono) .name(GET_PLUGIN_EXECUTOR) @@ -375,7 +378,6 @@ public Mono executeAction( executeActionMetaDTO.getHeaders()) .name(GET_ACTION_EXECUTION_RESULT) .tap(Micrometer.observation(observationRegistry)); - Mono editorConfigLabelMapMono = getEditorConfigLabelMap(datasourceStorageMono); return actionExecutionResultMono @@ -764,6 +766,8 @@ protected Mono verifyDatasourceAndMakeRequest( Mono executionMono = authenticationValidator .validateAuthentication(datasourceStorage) + .name(VALIDATE_AUTHENTICATION_DATASOURCE_STORAGE) + .tap(Micrometer.observation(observationRegistry)) .zipWhen(validatedDatasource -> datasourceContextService .getDatasourceContext(validatedDatasource, plugin) .tag("plugin", plugin.getPackageName()) @@ -909,37 +913,45 @@ protected Mono getActionExecutionResult( Mono actionDTOWithAutoGeneratedHeadersMono = setAutoGeneratedHeaders(plugin, actionDTO, httpHeaders); - Mono actionExecutionResultMono = - actionDTOWithAutoGeneratedHeadersMono.flatMap(actionDTO1 -> verifyDatasourceAndMakeRequest( + Mono actionExecutionResultMono = actionDTOWithAutoGeneratedHeadersMono + .flatMap(actionDTO1 -> verifyDatasourceAndMakeRequest( executeActionDTO, actionDTO, datasourceStorage, plugin, pluginExecutor) - .timeout(Duration.ofMillis(timeoutDuration))); + .timeout(Duration.ofMillis(timeoutDuration))) + .name(VERIFY_DATASOURCE_AND_MAKE_REQUEST) + .tap(Micrometer.observation(observationRegistry)); ActionConfiguration finalRawActionConfiguration = rawActionConfiguration; return actionExecutionResultMono .onErrorMap(executionExceptionMapper(actionDTO, timeoutDuration)) .onErrorResume(executionExceptionHandler(actionDTO)) .elapsed() - // Now send the analytics event for this execution - .flatMap(tuple1 -> { + .map(tuple1 -> { Long timeElapsed = tuple1.getT1(); - ActionExecutionResult result = tuple1.getT2(); - log.debug( "{}: Action {} with id {} execution time : {} ms", Thread.currentThread().getName(), actionDTO.getName(), actionDTO.getId(), timeElapsed); - - return sendExecuteAnalyticsEvent( + return tuple1; + }) + .doOnSuccess(tuple2 -> { + Long timeElapsed = tuple2.getT1(); + ActionExecutionResult result = tuple2.getT2(); + // Runs the analytics in the separate thread and immediately return the execution result + sendExecuteAnalyticsEvent( actionDTO, datasourceStorage, executeActionDTO, result, timeElapsed, finalRawActionConfiguration) - .thenReturn(result); - }); + .name(SEND_EXECUTE_ANALYTICS_EVENT) + .tap(Micrometer.observation(observationRegistry)) + .subscribeOn(Schedulers.boundedElastic()) + .subscribe(); + }) + .map(Tuple2::getT2); }); } @@ -1097,16 +1109,16 @@ private Mono sendExecuteAnalyticsEvent( request.setProperties(stringProperties); } - return Mono.justOrEmpty(actionDTO.getApplicationId()) + Mono applicationMono = Mono.justOrEmpty(actionDTO.getApplicationId()) .flatMap(applicationService::findById) - .defaultIfEmpty(new Application()) - .flatMap(application -> Mono.zip( - Mono.just(application), + .defaultIfEmpty(new Application()); + return Mono.zip( + applicationMono, sessionUserService.getCurrentUser(), newPageService.getNameByPageId(actionDTO.getPageId(), executeActionDto.getViewMode()), pluginService.getByIdWithoutPermissionCheck(actionDTO.getPluginId()), datasourceStorageService.getEnvironmentNameFromEnvironmentIdForAnalytics( - datasourceStorage.getEnvironmentId()))) + datasourceStorage.getEnvironmentId())) .flatMap(tuple -> { final Application application = tuple.getT1(); final User user = tuple.getT2();