Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MNG-8540] Add cache to API requests #2051

Merged
merged 5 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api;

import org.apache.maven.api.annotations.Nonnull;

/**
* Represents a repository backed by an IDE workspace, the output of a build session,
* or similar ad-hoc collections of artifacts. This repository is considered read-only
* within the context of a session, meaning it can only be used for artifact resolution,
* not for installation or deployment. This interface does not provide direct access
* to artifacts; that functionality is handled by a {@code WorkspaceReader}.
*/
public interface WorkspaceRepository extends Repository {

/**
* {@return the type of the repository, i.e. "workspace"}
*/
@Nonnull
@Override
default String getType() {
return "workspace";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api.cache;

import java.util.List;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.services.Request;
import org.apache.maven.api.services.Result;

/**
* Exception thrown when a batch request operation fails. This exception contains the results
* of all requests that were attempted, including both successful and failed operations.
* <p>
* The exception provides access to detailed results through {@link #getResults()}, allowing
* callers to determine which specific requests failed and why.
*
* @since 4.0.0
*/
@Experimental
public class BatchRequestException extends RuntimeException {

private final List<RequestResult<?, ?>> results;

/**
* Constructs a new BatchRequestException with the specified message and results.
*
* @param <REQ> The type of the request
* @param <REP> The type of the response
* @param message The error message describing the batch operation failure
* @param allResults List of results from all attempted requests in the batch
*/
public <REQ extends Request<?>, REP extends Result<REQ>> BatchRequestException(
String message, List<RequestResult<REQ, REP>> allResults) {
super(message);
this.results = List.copyOf(allResults);
}

/**
* Returns the list of results from all requests that were part of the batch operation.
* Each result contains the original request, the response (if successful), and any error
* that occurred during processing.
*
* @return An unmodifiable list of request results
*/
public List<RequestResult<?, ?>> getResults() {
return results;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,26 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api.services.model;
package org.apache.maven.api.cache;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.annotations.Nullable;

/**
* Factory for creating model caches.
* <p>
* The model cache is meant for exclusive consumption by the model builder and is opaque to the cache implementation.
* The cache is created once per session and is valid through the lifetime of the session.
* <p>
* The cache implementation could be annotated with {@code SessionScoped} to be created once per session, but
* this would make tests more complicated to write as they would all need to enter the session scope.
* Interface defining metadata for cache behavior and lifecycle management.
* Implementations can specify how long cached data should be retained.
*
* @since 4.0.0
*/
@Experimental
public interface ModelCacheFactory {
public interface CacheMetadata {

@Nonnull
ModelCache newInstance();
/**
* Returns the cache retention that should be applied to the associated data.
*
* @return The CacheRetention indicating how long data should be retained, or null if
* no specific cache retention is defined
*/
@Nullable
CacheRetention getCacheRetention();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api.cache;

import org.apache.maven.api.annotations.Experimental;

/**
* Enumeration defining different retention periods for cached data.
* Each value represents a specific scope and lifetime for cached items.
*
* @since 4.0.0
*/
@Experimental
public enum CacheRetention {
/**
* Data should be persisted across Maven invocations.
* Suitable for:
* - Dependency resolution results
* - Compilation outputs
* - Downloaded artifacts
*/
PERSISTENT,

/**
* Data should be retained for the duration of the current Maven session.
* Suitable for:
* - Build-wide configuration
* - Project model caching
* - Inter-module metadata
*/
SESSION_SCOPED,

/**
* Data should only be retained for the current build request.
* Suitable for:
* - Plugin execution results
* - Temporary build artifacts
* - Phase-specific data
*/
REQUEST_SCOPED,

/**
* Caching should be disabled for this data.
* Suitable for:
* - Sensitive information
* - Non-deterministic operations
* - Debug or development data
*/
DISABLED
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api.cache;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.services.MavenException;

/**
* Exception thrown when an error occurs during Maven execution.
* This exception wraps the original cause of the execution failure.
*
* @since 4.0.0
*/
@Experimental
public class MavenExecutionException extends MavenException {

/**
* Constructs a new MavenExecutionException with the specified cause.
*
* @param cause The underlying exception that caused the execution failure
*/
public MavenExecutionException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api.cache;

import java.util.List;
import java.util.function.Function;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.services.Request;
import org.apache.maven.api.services.Result;

/**
* Interface for caching request results in Maven. This cache implementation provides
* methods for executing and optionally caching both single requests and batches of requests.
* <p>
* The cache behavior is determined by the cache retention specified in the request's metadata.
* Results can be cached at different policies (forever, session, request, or not at all)
* based on the {@link CacheRetention} associated with the request.
*
* @since 4.0.0
* @see CacheMetadata
* @see RequestCacheFactory
*/
@Experimental
public interface RequestCache {

/**
* Executes and optionally caches a request using the provided supplier function. If caching is enabled
* for this session, the result will be cached and subsequent identical requests will return the cached
* value without re-executing the supplier.
* <p>
* The caching behavior is determined by the cache retention specified in the request's metadata.
* If an error occurs during execution, it will be cached and re-thrown for subsequent identical requests.
*
* @param <REQ> The request type
* @param <REP> The response type
* @param req The request object used as the cache key
* @param supplier The function to execute and cache the result
* @return The result from the supplier (either fresh or cached)
* @throws RuntimeException Any exception thrown by the supplier will be cached and re-thrown on subsequent calls
*/
<REQ extends Request<?>, REP extends Result<REQ>> REP request(REQ req, Function<REQ, REP> supplier);

/**
* Executes and optionally caches a batch of requests using the provided supplier function.
* This method allows for efficient batch processing of multiple requests.
* <p>
* The implementation may optimize the execution by:
* <ul>
* <li>Returning cached results for previously executed requests</li>
* <li>Grouping similar requests for batch processing</li>
* <li>Processing requests in parallel where appropriate</li>
* </ul>
*
* @param <REQ> The request type
* @param <REP> The response type
* @param req List of requests to process
* @param supplier Function to execute the batch of requests
* @return List of results corresponding to the input requests
* @throws BatchRequestException if any request in the batch fails
*/
<REQ extends Request<?>, REP extends Result<REQ>> List<REP> requests(
List<REQ> req, Function<List<REQ>, List<REP>> supplier);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api.cache;

import org.apache.maven.api.annotations.Experimental;

/**
* Factory interface for creating new RequestCache instances.
* Implementations should handle the creation and configuration of cache instances
* based on the current Maven session and environment.
*
* @since 4.0.0
* @see RequestCache
*/
@Experimental
public interface RequestCacheFactory {

/**
* Creates a new RequestCache instance.
* The created cache should be configured according to the current Maven session
* and environment settings.
*
* @return A new RequestCache instance
*/
RequestCache createCache();
}
Loading