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

CollectionBulkInsertOperation cancel 시 cancel 원인을 API 사용자가 알 수 없는 이슈 #528

Open
uhm0311 opened this issue Aug 17, 2022 · 5 comments
Assignees

Comments

@uhm0311
Copy link
Collaborator

uhm0311 commented Aug 17, 2022

// ArcusClient
private <T> Future<Map<String, CollectionOperationStatus>> asyncCollectionInsertBulk2(
        List<CollectionBulkInsert<T>> insertList) {

  final ConcurrentLinkedQueue<Operation> ops = new ConcurrentLinkedQueue<Operation>();

  final Map<String, CollectionOperationStatus> failedResult =
      new ConcurrentHashMap<String, CollectionOperationStatus>();

  final CountDownLatch latch = new CountDownLatch(insertList.size());

  for (final CollectionBulkInsert<T> insert : insertList) {
    Operation op = opFact.collectionBulkInsert(
            insert, new CollectionBulkInsertOperation.Callback() {
              public void receivedStatus(OperationStatus status) {
                // Nothing to do here because the user MUST search the result Map instance.
              }

              public void complete() {
                latch.countDown();
              }

              public void gotStatus(String key, OperationStatus status) {
                if (!status.isSuccess()) {
                  if (status instanceof CollectionOperationStatus) {
                    failedResult.put(key,
                            (CollectionOperationStatus) status);
                  } else {
                    failedResult.put(key,
                            new CollectionOperationStatus(status));
                  }
                }
              }
            });
    ops.add(op);
    addOp(insert.getMemcachedNode(), op);
  }

  ...

}

CollectionBulkInsertOperation.Callback.receivedStatus() 메소드는 비어 있다. 이는 Multi Key Operation이며, receivedStatus() 메소드 단에서는 어느 Key가 실패했는지 알 수 없기 때문이다. 해당 정보는 gotStatus() 메소드를 통해 전달해주어야 한다.

CollectionBulkInsertOperation.cancel() 호출 시 wasCancelled() 메소드를 통해 callback.receivedStatus() 메소드를 호출한다. cancel 동작 또한 연산 실패이므로 CollectionBulkInsertOperation의 failedResult에 포함되어야 하는데, receivedStatus() Callback으로는 Key 정보가 주어지지 않아 failedResult에 포함할 수 없다.

// BaseOperationImpl
public final void cancel(String cause) {
  cancelled = true;
  if (handlingNode != null) {
    cancelCause = "Cancelled (" + cause + " : (" + handlingNode.getNodeName() + ")" + ")";
  } else {
    cancelCause = "Cancelled (" + cause + ")";
  }
  wasCancelled();
  callback.complete();
}
// CollectionInsertOperationImpl
@Override
protected void wasCancelled() {
  getCallback().receivedStatus(STORE_CANCELED);
}
// CollectionBulkInsertOperation.Callback
public void receivedStatus(OperationStatus status) {
  // Nothing to do here because the user MUST search the result Map instance.
}

CollectionInsertOperationImpl.wasCancelled() 구현에 한해 callback.gotStatus() 메소드를 호출하도록 하여 failedResult에 cancel 원인이 담기도록 한다.

@jhpark816
Copy link
Collaborator

@uhm0311
위의 처리가 필요한 다른 연산이 존재하는 지 확인하고 알려주세요.

@uhm0311
Copy link
Collaborator Author

uhm0311 commented Jun 27, 2023

receivedStatus() 메소드에서 key를 알 수 없어서 OperationStatus를 정할 수 없는 경우는 CollectionBulkInsertOperation이 유일합니다.

@uhm0311
Copy link
Collaborator Author

uhm0311 commented Jun 29, 2023

Cacnel은 All or Nothing입니다.
Operation.cancel()이 호출되었다면 Future.get() 메소드 호출 시 Future의 값을 얻어오지 못하고 Exception이 발생합니다.
즉, 어떤 Key에 한해 Cancel 되었는지를 확인할 방법이 없습니다.
따라서 이 이슈는 Close 합니다.

@uhm0311 uhm0311 closed this as not planned Won't fix, can't repro, duplicate, stale Jun 29, 2023
@jhpark816 jhpark816 reopened this Jun 29, 2023
@jhpark816
Copy link
Collaborator

jhpark816 commented Jun 29, 2023

@uhm0311
본 이슈는 아래 경우에 의미가 있습니다.

  • multi op 연산에서 일부는 완료되고 나머지 일부만 cancel 처리하고,
    Future.get()에서 실패한 정보만 전달하는 경우
  • 만약, 모든 연산이 cancel 되면, exception 처리

생각하는 시간을 가지도록 하시죠.

@uhm0311
Copy link
Collaborator Author

uhm0311 commented Jan 26, 2024

현재 Multi op를 다루는 Future들은 모두 Operation 중 하나라도 Cancel 처리되었다면 Exception을 발생하는 것으로 되어 있습니다.

  • SMGetFuture
  • BroadcastFuture
  • BulkOperationFuture
  • CollectionGetBulkFuture
  • PipedCollectionFuture

일부의 결과라도 반환하도록 변경하면 하위 호환성이 깨질 수 있기 때문에 일부 결과를 반환하고 싶다면 getSome()과 같은 새로운 인터페이스를 제공하는 것이 나을 것 같습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants