chore: remove analytics execution from the critical path (#39757)
## Description - Pushed out the sendExecuteAnalyticsEvent from the critical path of returning action's execution result. - Improved the critical Path of sendExecuteAnalyticsEvent by running the application mono concurrent to other events. - Added more telemetry code around the execution flow. Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.All" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/13919689126> > Commit: ddf93dd06cd4facabdde5898d1cc40ce7dc4765f > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13919689126&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Tue, 18 Mar 2025 10:28:52 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced additional action tracking identifiers to support enhanced analytics and authentication validation. - **Refactor** - Optimized asynchronous operations for data retrieval to improve responsiveness. - Enhanced the flow and error handling of action execution, ensuring smoother and more reliable performance. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
d494ca4ee1
commit
20317c5825
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ import org.springframework.util.StringUtils;
|
|||
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 class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE
|
|||
: getCachedPluginForActionExecution(datasourceStorageMono)
|
||||
.name(GET_CACHED_PLUGIN_FOR_ACTION_EXECUTION)
|
||||
.tap(Micrometer.observation(observationRegistry));
|
||||
|
||||
Mono<PluginExecutor> pluginExecutorMono = pluginExecutorHelper
|
||||
.getPluginExecutor(pluginMono)
|
||||
.name(GET_PLUGIN_EXECUTOR)
|
||||
|
|
@ -375,7 +378,6 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE
|
|||
executeActionMetaDTO.getHeaders())
|
||||
.name(GET_ACTION_EXECUTION_RESULT)
|
||||
.tap(Micrometer.observation(observationRegistry));
|
||||
|
||||
Mono<Map> editorConfigLabelMapMono = getEditorConfigLabelMap(datasourceStorageMono);
|
||||
|
||||
return actionExecutionResultMono
|
||||
|
|
@ -764,6 +766,8 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE
|
|||
|
||||
Mono<ActionExecutionResult> 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 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE
|
|||
Mono<ActionDTO> actionDTOWithAutoGeneratedHeadersMono =
|
||||
setAutoGeneratedHeaders(plugin, actionDTO, httpHeaders);
|
||||
|
||||
Mono<ActionExecutionResult> actionExecutionResultMono =
|
||||
actionDTOWithAutoGeneratedHeadersMono.flatMap(actionDTO1 -> verifyDatasourceAndMakeRequest(
|
||||
Mono<ActionExecutionResult> 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 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE
|
|||
request.setProperties(stringProperties);
|
||||
}
|
||||
|
||||
return Mono.justOrEmpty(actionDTO.getApplicationId())
|
||||
Mono<Application> 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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user