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

Refactored data clumps with the help of LLMs (research project) #2497

Merged
merged 7 commits into from
Aug 5, 2024
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
2 changes: 2 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github: [velo]
patreon: velo132
1 change: 1 addition & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ updates:
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 100
99 changes: 99 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# ----------------------------------------------------------------------------
# Copyright 2012-2014 The Feign Authors
#
# The Netty Project 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:
#
# https://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.
# ----------------------------------------------------------------------------
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
name: "CodeQL"

on:
push:
branches: ["master"]
pull_request:
# The branches below must be a subset of the branches above
branches: ["master"]
schedule:
- cron: '0 13 * * 3'

permissions:
contents: read

jobs:
analyze:
permissions:
actions: read # for github/codeql-action/init to get workflow details
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/analyze to upload SARIF results
name: Analyze
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
language: ['java']
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection

steps:
- name: Checkout repository
uses: actions/checkout@v4

# Cache .m2/repository
- name: Cache local Maven repository
uses: actions/cache@v3
continue-on-error: true
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ matrix.language }} ${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-${{ matrix.language }}
${{ runner.os }}-maven-

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
# - name: Autobuild
# uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl

# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
- name: Setup Java JDK
uses: actions/[email protected]
with:
distribution: 'temurin'
java-version: '21'

- name: Compile project
run: ./mvnw -B -ntp clean package -Pquickbuild -Dtoolchain.skip=true

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
4 changes: 2 additions & 2 deletions core/src/main/java/feign/AsyncFeign.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 The Feign Authors
* Copyright 2012-2024 The Feign Authors
*
* Licensed 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
Expand Down Expand Up @@ -210,7 +210,7 @@ closeAfterDecode, decodeVoid, responseInterceptorChain()),
responseHandler, logger, logLevel,
propagationPolicy, methodInfoResolver,
new RequestTemplateFactoryResolver(encoder, queryMapEncoder),
options, decoder, errorDecoder);
options);
final ReflectiveFeign<C> feign =
new ReflectiveFeign<>(contract, methodHandlerFactory, invocationHandlerFactory,
defaultContextSupplier);
Expand Down
99 changes: 40 additions & 59 deletions core/src/main/java/feign/AsynchronousMethodHandler.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 The Feign Authors
* Copyright 2012-2024 The Feign Authors
*
* Licensed 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
Expand All @@ -15,8 +15,6 @@

import feign.InvocationHandlerFactory.MethodHandler;
import feign.Request.Options;
import feign.codec.Decoder;
import feign.codec.ErrorDecoder;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
Expand All @@ -31,49 +29,28 @@

final class AsynchronousMethodHandler<C> implements MethodHandler {

private final MethodMetadata metadata;
private final Target<?> target;
private final AsyncClient<C> client;
private final Retryer retryer;
private final List<RequestInterceptor> requestInterceptors;
private final Logger logger;
private final Logger.Level logLevel;
private final RequestTemplate.Factory buildTemplateFromArgs;
private final Options options;
private final ExceptionPropagationPolicy propagationPolicy;
private final C requestContext;
private final AsyncResponseHandler asyncResponseHandler;
private final MethodInfo methodInfo;


private AsynchronousMethodHandler(Target<?> target, AsyncClient<C> client, Retryer retryer,
List<RequestInterceptor> requestInterceptors,
Logger logger, Logger.Level logLevel, MethodMetadata metadata,
RequestTemplate.Factory buildTemplateFromArgs, Options options,
AsyncResponseHandler asyncResponseHandler, ExceptionPropagationPolicy propagationPolicy,
C requestContext, MethodInfo methodInfo) {

this.target = checkNotNull(target, "target");
this.client = checkNotNull(client, "client for %s", target);
this.retryer = checkNotNull(retryer, "retryer for %s", target);
this.requestInterceptors =
checkNotNull(requestInterceptors, "requestInterceptors for %s", target);
this.logger = checkNotNull(logger, "logger for %s", target);
this.logLevel = checkNotNull(logLevel, "logLevel for %s", target);
this.metadata = checkNotNull(metadata, "metadata for %s", target);
this.buildTemplateFromArgs = checkNotNull(buildTemplateFromArgs, "metadata for %s", target);
this.options = checkNotNull(options, "options for %s", target);
this.propagationPolicy = propagationPolicy;
private final MethodHandlerConfiguration methodHandlerConfiguration;

private AsynchronousMethodHandler(MethodHandlerConfiguration methodHandlerConfiguration,
AsyncClient<C> client, AsyncResponseHandler asyncResponseHandler, C requestContext,
MethodInfo methodInfo) {
this.methodHandlerConfiguration =
checkNotNull(methodHandlerConfiguration, "methodHandlerConfiguration");
this.client = checkNotNull(client, "client for %s", methodHandlerConfiguration.getTarget());
this.requestContext = requestContext;
this.asyncResponseHandler = asyncResponseHandler;
this.methodInfo = methodInfo;
}

@Override
public Object invoke(Object[] argv) throws Throwable {
RequestTemplate template = buildTemplateFromArgs.create(argv);
RequestTemplate template = methodHandlerConfiguration.getBuildTemplateFromArgs().create(argv);
Options options = findOptions(argv);
Retryer retryer = this.retryer.clone();
Retryer retryer = this.methodHandlerConfiguration.getRetryer().clone();
try {
if (methodInfo.isAsyncReturnType()) {
return executeAndDecode(template, options, retryer);
Expand All @@ -94,8 +71,10 @@ private CompletableFuture<Object> executeAndDecode(RequestTemplate template,
.whenComplete((response, throwable) -> {
if (throwable != null) {
if (!resultFuture.isDone() && shouldRetry(retryer, throwable, resultFuture)) {
if (logLevel != Logger.Level.NONE) {
logger.logRetry(metadata.configKey(), logLevel);
if (methodHandlerConfiguration.getLogLevel() != Logger.Level.NONE) {
methodHandlerConfiguration.getLogger().logRetry(
methodHandlerConfiguration.getMetadata().configKey(),
methodHandlerConfiguration.getLogLevel());
}

resultFuture.setInner(
Expand Down Expand Up @@ -159,7 +138,7 @@ private boolean shouldRetry(Retryer retryer,
return true;
} catch (RetryableException th) {
Throwable cause = th.getCause();
if (propagationPolicy == UNWRAP && cause != null) {
if (methodHandlerConfiguration.getPropagationPolicy() == UNWRAP && cause != null) {
resultFuture.completeExceptionally(cause);
} else {
resultFuture.completeExceptionally(th);
Expand All @@ -171,8 +150,10 @@ private boolean shouldRetry(Retryer retryer,
private CompletableFuture<Object> executeAndDecode(RequestTemplate template, Options options) {
Request request = targetRequest(template);

if (logLevel != Logger.Level.NONE) {
logger.logRequest(metadata.configKey(), logLevel, request);
if (methodHandlerConfiguration.getLogLevel() != Logger.Level.NONE) {
methodHandlerConfiguration.getLogger().logRequest(
methodHandlerConfiguration.getMetadata().configKey(),
methodHandlerConfiguration.getLogLevel(), request);
}

long start = System.nanoTime();
Expand All @@ -186,8 +167,10 @@ private CompletableFuture<Object> executeAndDecode(RequestTemplate template, Opt
: new CompletionException(throwable);
if (completionException.getCause() instanceof IOException) {
IOException ioException = (IOException) completionException.getCause();
if (logLevel != Logger.Level.NONE) {
logger.logIOException(metadata.configKey(), logLevel, ioException,
if (methodHandlerConfiguration.getLogLevel() != Logger.Level.NONE) {
methodHandlerConfiguration.getLogger().logIOException(
methodHandlerConfiguration.getMetadata().configKey(),
methodHandlerConfiguration.getLogLevel(), ioException,
elapsedTime(start));
}

Expand All @@ -210,29 +193,30 @@ private static Response ensureRequestIsSet(Response response,

private CompletableFuture<Object> handleResponse(Response response, long elapsedTime) {
return asyncResponseHandler.handleResponse(
metadata.configKey(), response, methodInfo.underlyingReturnType(), elapsedTime);
methodHandlerConfiguration.getMetadata().configKey(), response,
methodInfo.underlyingReturnType(), elapsedTime);
}

private long elapsedTime(long start) {
return TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
}

private Request targetRequest(RequestTemplate template) {
for (RequestInterceptor interceptor : requestInterceptors) {
for (RequestInterceptor interceptor : methodHandlerConfiguration.getRequestInterceptors()) {
interceptor.apply(template);
}
return target.apply(template);
return methodHandlerConfiguration.getTarget().apply(template);
}

private Options findOptions(Object[] argv) {
if (argv == null || argv.length == 0) {
return this.options;
return this.methodHandlerConfiguration.getOptions();
}
return Stream.of(argv)
.filter(Options.class::isInstance)
.map(Options.class::cast)
.findFirst()
.orElse(this.options);
.orElse(this.methodHandlerConfiguration.getOptions());
}

static class Factory<C> implements MethodHandler.Factory<C> {
Expand All @@ -247,18 +231,14 @@ static class Factory<C> implements MethodHandler.Factory<C> {
private final MethodInfoResolver methodInfoResolver;
private final RequestTemplateFactoryResolver requestTemplateFactoryResolver;
private final Options options;
private final Decoder decoder;
private final ErrorDecoder errorDecoder;

Factory(AsyncClient<C> client, Retryer retryer, List<RequestInterceptor> requestInterceptors,
AsyncResponseHandler responseHandler,
Logger logger, Logger.Level logLevel,
ExceptionPropagationPolicy propagationPolicy,
MethodInfoResolver methodInfoResolver,
RequestTemplateFactoryResolver requestTemplateFactoryResolver,
Options options,
Decoder decoder,
ErrorDecoder errorDecoder) {
Options options) {
this.client = checkNotNull(client, "client");
this.retryer = checkNotNull(retryer, "retryer");
this.requestInterceptors = checkNotNull(requestInterceptors, "requestInterceptors");
Expand All @@ -270,19 +250,20 @@ static class Factory<C> implements MethodHandler.Factory<C> {
this.requestTemplateFactoryResolver =
checkNotNull(requestTemplateFactoryResolver, "requestTemplateFactoryResolver");
this.options = checkNotNull(options, "options");
this.errorDecoder = checkNotNull(errorDecoder, "errorDecoder");
this.decoder = checkNotNull(decoder, "decoder");
}

@Override
public MethodHandler create(Target<?> target,
MethodMetadata md,
MethodMetadata metadata,
C requestContext) {
final RequestTemplate.Factory buildTemplateFromArgs =
requestTemplateFactoryResolver.resolve(target, md);
return new AsynchronousMethodHandler<C>(target, client, retryer, requestInterceptors,
logger, logLevel, md, buildTemplateFromArgs, options, responseHandler,
propagationPolicy, requestContext,
methodInfoResolver.resolve(target.type(), md.method()));
requestTemplateFactoryResolver.resolve(target, metadata);

MethodHandlerConfiguration methodHandlerConfiguration =
new MethodHandlerConfiguration(metadata, target, retryer, requestInterceptors, logger,
logLevel, buildTemplateFromArgs, options, propagationPolicy);
return new AsynchronousMethodHandler<C>(methodHandlerConfiguration, client, responseHandler,
requestContext, methodInfoResolver.resolve(target.type(), metadata.method()));
}
}
}
Loading
Loading