在 Manus 中运行任何 Skill
一键导入
一键导入
一键在 Manus 中运行任何 Skill
开始使用debugging
星标1
分支0
更新时间2026年1月29日 12:49
Reactive Streams 디버깅 전략, 로깅, 에러 추적
安装
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
SKILL.md
readonly菜单
Reactive Streams 디버깅 전략, 로깅, 에러 추적
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Backpressure 개념, 전략, 구현 가이드
코드 품질 가이드, 클린 코드 원칙, 리팩토링 패턴
Reactive Operator 구현 패턴, 체이닝, 변환
Reactive Streams 전체 규약 (39개 규칙) 상세 설명
테스트 작성 전략, JUnit 5, Reactive Streams TCK
| name | debugging |
| description | Reactive Streams 디버깅 전략, 로깅, 에러 추적 |
기존 동기 코드와 달리 Reactive 코드는:
public class SignalLogger<T> implements Subscriber<T> {
private final Subscriber<T> actual;
private final String name;
public SignalLogger(Subscriber<T> actual, String name) {
this.actual = actual;
this.name = name;
}
@Override
public void onSubscribe(Subscription s) {
log("onSubscribe(%s)", s);
actual.onSubscribe(new LoggingSubscription(s));
}
@Override
public void onNext(T item) {
log("onNext(%s)", item);
actual.onNext(item);
}
@Override
public void onError(Throwable t) {
log("onError(%s)", t.getMessage());
actual.onError(t);
}
@Override
public void onComplete() {
log("onComplete()");
actual.onComplete();
}
private void log(String format, Object... args) {
System.out.printf("[%s][%s] %s%n",
Thread.currentThread().getName(),
name,
String.format(format, args)
);
}
class LoggingSubscription implements Subscription {
private final Subscription actual;
@Override
public void request(long n) {
log("request(%d)", n);
actual.request(n);
}
@Override
public void cancel() {
log("cancel()");
actual.cancel();
}
}
}
publisher.subscribe(new SignalLogger<>(subscriber, "MySubscriber"));
[main] MySubscriber: onSubscribe(ArraySubscription@1234)
[main] MySubscriber: request(2)
[main] MySubscriber: onNext(1)
[main] MySubscriber: onNext(2)
[main] MySubscriber: request(3)
[main] MySubscriber: onNext(3)
[main] MySubscriber: onComplete()
// Bug: request를 기다리지 않고 바로 발행
@Override
public void subscribe(Subscriber<? super T> s) {
s.onSubscribe(subscription);
for (T item : items) {
s.onNext(item); // Rule 1.1 위반!
}
s.onComplete();
}
증상: Subscriber가 준비되기 전에 데이터 도착
해결:
@Override
public void request(long n) {
for (int i = 0; i < n && index < items.length; i++) {
subscriber.onNext(items[index++]);
}
}
// Bug: 여러 번 완료 시그널
if (hasError) {
subscriber.onError(error);
}
subscriber.onComplete(); // Rule 1.7 위반!
해결:
if (hasError) {
subscriber.onError(error);
return; // 조기 반환
}
subscriber.onComplete();
// Bug: 동시성 문제
private long requested = 0;
public void request(long n) {
requested += n; // 스레드 안전하지 않음!
drain();
}
해결:
private final AtomicLong requested = new AtomicLong(0);
public void request(long n) {
requested.addAndGet(n);
drain();
}
// Bug: cancel 후에도 계속 발행
public void request(long n) {
for (int i = 0; i < n; i++) {
subscriber.onNext(items[index++]); // cancel 체크 안함!
}
}
해결:
public void request(long n) {
for (int i = 0; i < n && !cancelled.get(); i++) {
subscriber.onNext(items[index++]);
}
}
public enum State {
WAITING, SUBSCRIBED, COMPLETED, ERROR, CANCELLED
}
private void transitionTo(State newState) {
State oldState = state.getAndSet(newState);
log("State: %s -> %s", oldState, newState);
// 잘못된 전이 감지
if (oldState == State.COMPLETED || oldState == State.ERROR) {
log("WARNING: Transition from terminal state!");
}
}
시그널 순서 확인
동시성 확인
cancel 처리 확인
에러 전파 확인
reactive-spec: 규약 상세testing: 테스트 전략