Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
mercyblitz committed Jan 24, 2025
1 parent b664374 commit b603ccc
Show file tree
Hide file tree
Showing 11 changed files with 600 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,17 @@ protected Bulkhead createEntry(String name) {
* {@inheritDoc}
*/
@Override
protected void beforeExecute(Bulkhead entry, Resilience4jContext context) {
entry.acquirePermission();
protected void beforeExecute(Resilience4jContext<Bulkhead> context) {
Bulkhead bulkhead = context.getEntry();
bulkhead.acquirePermission();
}

/**
* {@inheritDoc}
*/
@Override
protected <V> void afterExecute(Bulkhead entry, Long duration, V result, Throwable failure, Resilience4jContext context) {
entry.onComplete();
protected void afterExecute(Resilience4jContext<Bulkhead> context) {
Bulkhead bulkhead = context.getEntry();
bulkhead.onComplete();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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 io.microsphere.resilience4j.circuitbreaker;

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.microsphere.resilience4j.common.Resilience4jContext;
import io.microsphere.resilience4j.common.Resilience4jTemplate;

import java.util.concurrent.TimeUnit;

/**
* {@link Resilience4jTemplate} for {@link CircuitBreaker}
*
* @author <a href="mailto:[email protected]">Mercy<a/>
* @see CircuitBreaker
* @see CircuitBreakerConfig
* @see CircuitBreakerRegistry
* @see Resilience4jTemplate
* @since 1.0.0
*/
public class CircuitBreakerTemplate extends Resilience4jTemplate<CircuitBreaker, CircuitBreakerConfig, CircuitBreakerRegistry> {

public CircuitBreakerTemplate(CircuitBreakerRegistry registry) {
super(registry);
}

/**
* Create the {@link CircuitBreaker}
*
* @param name the name of the Resilience4j's entry
* @return non-null
*/
@Override
protected CircuitBreaker createEntry(String name) {
CircuitBreakerRegistry registry = super.getRegistry();
return registry.circuitBreaker(name, super.getConfiguration(name), registry.getTags());
}

/**
* {@inheritDoc}
*/
@Override
protected void beforeExecute(Resilience4jContext<CircuitBreaker> context) {
CircuitBreaker circuitBreaker = context.getEntry();
circuitBreaker.acquirePermission();
context.setStartTime(circuitBreaker.getCurrentTimestamp());
}

/**
* {@inheritDoc}
*/
@Override
protected void afterExecute(Resilience4jContext<CircuitBreaker> context) {
CircuitBreaker circuitBreaker = context.getEntry();
Throwable failure = context.getFailure();
long startTime = context.getStartTime();
long duration = circuitBreaker.getCurrentTimestamp() - startTime;
TimeUnit timeUnit = circuitBreaker.getTimestampUnit();
if (failure == null) {
Object result = context.getResult();
if (result == null) {
circuitBreaker.onSuccess(duration, timeUnit);
} else {
circuitBreaker.onResult(duration, timeUnit, result);
}
} else {
circuitBreaker.onError(duration, timeUnit, failure);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,126 @@
*/
package io.microsphere.resilience4j.common;

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.core.lang.NonNull;
import io.github.resilience4j.core.lang.Nullable;

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

import static io.microsphere.util.Assert.assertNotNull;
import static java.util.Collections.emptyMap;
import static java.util.Collections.unmodifiableMap;

/**
* The context of Resilience4j
*
* @param <E> the type of Resilience4j's entry, e.g., {@link CircuitBreaker}
* @author <a href="mailto:[email protected]">Mercy<a/>
* @see Resilience4jModule
* @since 1.0.0
*/
public class Resilience4jContext {
public class Resilience4jContext<E> {

/**
* The name of Resilience4j's entry
*/
private final String entryName;

/**
* The Resilience4j's entry, e.g., {@link CircuitBreaker}
*/
@NonNull
private final E entry;

/**
* The start time of the execution
*/
@Nullable
private Long startTime;

/**
* The execution result
*/
@Nullable
Object result;

/**
* The optional {@link Throwable} instance, if <code>null</code>, it means the execution is successful
*/
@Nullable
Throwable failure;

/**
* The attributes
*/
@Nullable
private Map<String, Object> attributes;

Resilience4jContext(String entryName, E entry) {
assertNotNull(entryName, "The entry name must not be null.");
assertNotNull(entry, "The entry must not be null.");
this.entryName = entryName;
this.entry = entry;
}

/**
* Get the name of Resilience4j's entry
*
* @return non-null
*/
public String getEntryName() {
return entryName;
}

/**
* Get the Resilience4j's entry, e.g., {@link CircuitBreaker}
*
* @return the Resilience4j's entry, e.g., {@link CircuitBreaker}
*/
public E getEntry() {
return entry;
}

/**
* Set the start time of the execution
*
* @param startTime the start time of the execution
*/
public void setStartTime(Long startTime) {
this.startTime = startTime;
}

/**
* Get the start time of the execution
*
* @return <code>null</code> if {@link #setStartTime(Long)} method will be invoked
*/
@Nullable
public Long getStartTime() {
return startTime;
}

/**
* Set the result of the execution
*
* @return <code>null</code> if the target callback does not return value or is failed
*/
@Nullable
public Object getResult() {
return result;
}

/**
* Set the failure of the execution
*
* @return <code>null</code> if the target callback executes successfully
*/
@Nullable
public Throwable getFailure() {
return failure;
}

/**
* Set the attribute name and value.
*
Expand Down Expand Up @@ -97,8 +200,10 @@ public <T> T removeAttribute(String name) {
* @return {@link Resilience4jContext}
*/
public Resilience4jContext removeAttributes() {
Map<String, Object> attributes = getOrCreateAttributes();
attributes.clear();
Map<String, Object> attributes = this.attributes;
if (attributes != null) {
attributes.clear();
}
return this;
}

Expand All @@ -123,4 +228,16 @@ protected Map<String, Object> getOrCreateAttributes() {
}
return attributes;
}

@Override
public String toString() {
return "Resilience4jContext{" +
"entryName='" + entryName + '\'' +
", entry=" + entry +
", startTime=" + startTime +
", result=" + result +
", failure=" + failure +
", attributes=" + attributes +
'}';
}
}
Loading

0 comments on commit b603ccc

Please sign in to comment.