Skip to content

Commit

Permalink
Add AttributeAccessor & Add total timeout control to Resilience4j
Browse files Browse the repository at this point in the history
  • Loading branch information
chenzhiguo committed May 8, 2024
1 parent b317123 commit 9cf88ee
Show file tree
Hide file tree
Showing 22 changed files with 181 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,15 @@
*/
package com.jd.live.agent.bootstrap.bytekit.context;

import com.jd.live.agent.bootstrap.util.AttributeAccessorSupport;
import lombok.Getter;
import lombok.Setter;

import java.util.HashMap;
import java.util.Map;

/**
* An abstract class representing an executable context.
* This class provides a structure to hold information related to an executable task or operation.
*/
public abstract class ExecutableContext {
public abstract class ExecutableContext extends AttributeAccessorSupport {

/**
* The type of the executable.
Expand Down Expand Up @@ -59,11 +57,6 @@ public abstract class ExecutableContext {
@Getter
protected Throwable throwable;

/**
* A map of attributes associated with the executable context.
*/
protected Map<String, Object> attributes;

/**
* Creates a new instance of ExecutableContext.
*
Expand Down Expand Up @@ -96,32 +89,4 @@ public boolean isSuccess() {
return throwable == null;
}

/**
* Adds an attribute to the executable context.
*
* @param key the key for the attribute
* @param obj the value of the attribute
* @throws NullPointerException if the key is {@code null} or empty
*/
public void addAttribute(String key, Object obj) {
if (key != null && !key.isEmpty()) {
if (attributes == null) {
attributes = new HashMap<>();
}
attributes.put(key, obj);
}
}

/**
* Retrieves an attribute from the executable context.
*
* @param key the key for the attribute
* @param <T> the type of the attribute
* @return the value of the attribute, or {@code null} if the key is {@code null} or empty, or the attribute is not found
*/
@SuppressWarnings("unchecked")
public <T> T getAttribute(String key) {
return key == null || key.isEmpty() ? null : (T) attributes.get(key);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright © ${year} ${owner} (${email})
*
* 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
*
* 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 com.jd.live.agent.bootstrap.util;

public interface AttributeAccessor {

/**
* Retrieves an attribute by key.
*
* @param key The key of the attribute to retrieve.
* @return The value of the attribute, or null if not found.
*/
<T> T getAttribute(String key);

/**
* Sets or replaces an attribute with the specified key and value.
*
* @param key The key of the attribute.
* @param value The value of the attribute.
*/
void setAttribute(String key, Object value);

/**
* Removes an attribute by its key.
*
* @param key The key of the attribute to remove.
* @return The removed attribute, or null if the attribute was not found.
*/
<T> T removeAttribute(String key);

boolean hasAttribute(String key);

String[] attributeNames();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright © ${year} ${owner} (${email})
*
* 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
*
* 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 com.jd.live.agent.bootstrap.util;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;

public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {

private Map<String, Object> attributes;

public AttributeAccessorSupport() {
}

public void setAttribute(String key, Object value) {
if (key != null && value != null) {
if (attributes == null) {
attributes = new LinkedHashMap<>();
}
attributes.put(key, value);
}
}

public <T> T getAttribute(String key) {
return key == null || attributes == null ? null : (T) attributes.get(key);
}

public <T> T removeAttribute(String key) {
if (key != null && attributes != null) {
return (T) attributes.remove(key);
}
return null;
}

public boolean hasAttribute(String key) {
return this.attributes.containsKey(key);
}

public String[] attributeNames() {
return this.attributes.keySet().toArray(new String[0]);
}

protected void copyAttributesFrom(AttributeAccessor source) {
String[] attributeNames = source.attributeNames();
String[] var3 = attributeNames;
int var4 = attributeNames.length;

for (int var5 = 0; var5 < var4; ++var5) {
String attributeName = var3[var5];
this.setAttribute(attributeName, source.getAttribute(attributeName));
}
}

public boolean equals(Object other) {
if (this == other) {
return true;
} else if (!(other instanceof AttributeAccessorSupport)) {
return false;
} else {
AttributeAccessorSupport that = (AttributeAccessorSupport) other;
return this.attributes.equals(that.attributes);
}
}

public int hashCode() {
return this.attributes.hashCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package com.jd.live.agent.governance.context.bag;

import com.jd.live.agent.bootstrap.util.AttributeAccessor;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
Expand All @@ -28,7 +30,7 @@
* iterating over cargos and attributes in various ways to suit different use cases.
* </p>
*/
public interface Carrier {
public interface Carrier extends AttributeAccessor {

String ATTRIBUTE_FAILOVER_UNIT = "x-live-failover-unit";

Expand Down Expand Up @@ -249,28 +251,4 @@ default void traverse(BiConsumer<String, String> consumer) {
}
}

/**
* Retrieves an attribute by key.
*
* @param key The key of the attribute to retrieve.
* @return The value of the attribute, or null if not found.
*/
<T> T getAttribute(String key);

/**
* Sets or replaces an attribute with the specified key and value.
*
* @param key The key of the attribute.
* @param value The value of the attribute.
*/
void setAttribute(String key, Object value);

/**
* Removes an attribute by its key.
*
* @param key The key of the attribute to remove.
* @return The removed attribute, or null if the attribute was not found.
*/
<T> T removeAttribute(String key);

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@
*/
package com.jd.live.agent.governance.context.bag;

import com.jd.live.agent.bootstrap.util.AttributeAccessorSupport;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class Courier implements Carrier {
public class Courier extends AttributeAccessorSupport implements Carrier {

protected Map<String, Cargo> tags;

protected Map<String, Object> attributes;

@Override
public Collection<Cargo> getCargos() {
return tags == null ? null : tags.values();
Expand Down Expand Up @@ -78,28 +78,4 @@ public void removeCargo(String key) {
}
}

@Override
@SuppressWarnings("unchecked")
public <T> T getAttribute(String key) {
return key == null || attributes == null ? null : (T) attributes.get(key);
}

@Override
public void setAttribute(String key, Object value) {
if (key != null && value != null) {
if (attributes == null) {
attributes = new HashMap<>();
}
attributes.put(key, value);
}
}

@SuppressWarnings("unchecked")
@Override
public <T> T removeAttribute(String key) {
if (key != null && attributes != null) {
return (T) attributes.remove(key);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
*/
public interface Retrier {

String DEADLINE_KEY = "deadline";

/**
* Execute retry logic
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.jd.live.agent.governance.request;

import com.jd.live.agent.bootstrap.util.AttributeAccessorSupport;
import lombok.Getter;

import java.util.HashSet;
Expand All @@ -31,7 +32,7 @@
* @param <T> The type of the original request object this class wraps.
*/
@Getter
public abstract class AbstractServiceRequest<T> implements ServiceRequest {
public abstract class AbstractServiceRequest<T> extends AttributeAccessorSupport implements ServiceRequest {

/**
* The original request object associated with this service request.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package com.jd.live.agent.governance.request;

import com.jd.live.agent.bootstrap.util.AttributeAccessor;

/**
* Represents a general request interface.
* <p>
Expand All @@ -24,7 +26,7 @@
*
* @since 1.0.0
*/
public interface Request {
public interface Request extends AttributeAccessor {

/**
* A constant key used for identifying sticky sessions in live services.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.jd.live.agent.governance.response;

import com.jd.live.agent.bootstrap.util.AttributeAccessorSupport;
import lombok.Getter;

/**
Expand All @@ -23,7 +24,7 @@
* @since 1.0.0
*/
@Getter
public abstract class AbstractServiceResponse<T> implements ServiceResponse {
public abstract class AbstractServiceResponse<T> extends AttributeAccessorSupport implements ServiceResponse {

protected final T response;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
*/
package com.jd.live.agent.governance.response;

import java.io.Serializable;
import com.jd.live.agent.bootstrap.util.AttributeAccessor;

/**
* Response
*
* @since 1.0.0
*/
public interface Response extends Serializable {
public interface Response extends AttributeAccessor {

/**
* Response Code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,16 @@ public Resilience4jRetrier(RetryPolicy policy) {
RetryConfig config = RetryConfig.custom()
.maxAttempts(policy.getRetry() + 1)
.waitDuration(Duration.ofMillis(policy.getRetryInterval()))
.retryOnResult(response -> policy.isRetry(((Response) response).getCode()))
.retryOnResult(response -> {
Response rsp = (Response) response;
if (!rsp.hasAttribute(DEADLINE_KEY) && policy.getTimeout() > 0) {
rsp.setAttribute(DEADLINE_KEY, System.currentTimeMillis() + policy.getTimeout());
}
if (rsp.hasAttribute(DEADLINE_KEY) && System.currentTimeMillis() > (Long) rsp.getAttribute(DEADLINE_KEY)) {
return false;
}
return policy.isRetry(((Response) response).getCode());
})
.retryOnException(policy::isRetry)
.failAfterMaxAttempts(true)
.build();
Expand All @@ -56,6 +65,7 @@ public Resilience4jRetrier(RetryPolicy policy) {
public <T extends Response> T execute(Supplier<T> supplier) {
// TODO retry timeout
return retry.executeSupplier(supplier);

}

/**
Expand Down
Loading

0 comments on commit 9cf88ee

Please sign in to comment.