jam2in / arcus-java-client

Arcus Java client
Apache License 2.0
0 stars 0 forks source link

응용이 cancel한 operations은 node의 queue에서 언제 제거되는 지를 검증 #29

Closed jhpark816 closed 4 years ago

jhpark816 commented 8 years ago

응용이 요청한 operations이 아래 queue 중에 있을 시에 언제 queue에서 인지되고 빠지는 가를 확인.

whchoi83 commented 8 years ago

응용이 cancel 한 operation 을 제거하는 곳은 TCPMemcachedNodeImpl.preparePending 입니다.

    private boolean preparePending() {
        // Copy the input queue into the write queue.
        copyInputQueue();

        // Now check the ops
        Operation nextOp=getCurrentWriteOp();
        while(nextOp != null && nextOp.isCancelled()) {
            getLogger().info("Removing cancelled operation: %s", nextOp);
            removeCurrentWriteOp();
            nextOp=getCurrentWriteOp();
        }
        return nextOp != null;
    }

위 method 는 fillWriteBuffer 에서만 호출되는데, 응용이 cancel 한 operation 은 inputQueue 와 writeQueue 에서만 제거하는 것으로 판단됩니다. readQueue 에 있는 operation 은 이미 서버에서 처리되어 response 가 오기 때문에 받아서 처리까지는 합니만.

Future.cancel 을 호출한 시점에 사용자에게 return 되는 callback 함수에서 future 의 latch.down 은 처리하기 때문에 사용자한테 값이 return 되지는 않습니다. 아래는 Operation.cancel() 구현체와 (OperationFuture.cancel 에서 호출합니다.) callback 함수의 예로 MemcachedClient.asyncGet() 함수(MemcachedClient.get() 에서 호출) 입니다.

BaseOperationImpl.cancel()

    public final void cancel(String cause) {
        cancelled=true;
        cancelCause = "Cancelled (" + cause + ")";
        wasCancelled();
        callback.complete();
    }

MemcachedClient.asyncGet()

        Operation op=opFact.get(key,
                new GetOperation.Callback() {
            private Future<T> val=null;
            public void receivedStatus(OperationStatus status) {
                rv.set(val);
            }
            public void gotData(String k, int flags, byte[] data) {
                assert key.equals(k) : "Wrong key returned";
                val=tcService.decode(tc,
                    new CachedData(flags, data, tc.getMaxSize()));
            }
            public void complete() {
                // FIXME weird...
                if (localCacheManager != null) {
                    localCacheManager.put(key, val, operationTimeout);
                }
                latch.countDown();
            }});

코드 분석과 테스트 해보면서 생각해보니 예전에도 질문하신적이 있어서 이렇게 답변을 드렸던 것 같은데, 완전히 잊고 있었네요. 당시에는 코드의 이해도도 떨어지는 상태여서 기억에 제대로 남아있지 않았던 것 같습니다.

해당 내용은 정리하는 것이 필요할 것 같습니다.