如何保证 AWS SNS deleteEndpoint 已被删除
How to guarantee an AWS SNS deleteEndpoint has been deleted
如何确保在创建具有相同令牌的新 SNS 应用程序端点之前安全删除我的 SNS 应用程序端点?我有一个带有 ProgressListner 的删除方法,但是当我检查已删除的端点时,它仍然存在很短的时间。
我预计在收到 CLIENT_REQUEST_SUCCESS_EVENT 时删除已 100% 完成。我使用的是 AmazonSNSClient 而不是 AmazonSNSAsyncClient
public void deleteEndpoint(final String applicationArn, final String token) {
LOG.fine(String.format("Deleting endpoint by token for appArn=%s, token=%s", applicationArn, token));
Endpoint endpoint = findEndpointByToken(applicationArn, token);
if (endpoint != null) {
DeleteEndpointRequest der = new DeleteEndpointRequest().withEndpointArn(endpoint.getEndpointArn());
der.withGeneralProgressListener(new ProgressListener() {
public void progressChanged(ProgressEvent event) {
ProgressEventType eventType = event.getEventType();
System.out.println(eventType);
if (eventType.equals(ProgressEventType.CLIENT_REQUEST_SUCCESS_EVENT)) {
Endpoint exists = findEndpointByToken(applicationArn, token);
//This I expect this to be null but its only null after a few seconds
}
}
});
LOG.info(String.format("Deleted endpoint by token for appArn=%s, token=%s", applicationArn, token));
}
}
事件的输出是
CLIENT_REQUEST_STARTED_EVENT
HTTP_REQUEST_STARTED_EVENT
HTTP_REQUEST_COMPLETED_EVENT
RESPONSE_CONTENT_LENGTH_EVENT
HTTP_RESPONSE_STARTED_EVENT
RESPONSE_BYTE_TRANSFER_EVENT
HTTP_RESPONSE_COMPLETED_EVENT
CLIENT_REQUEST_SUCCESS_EVENT
SNS是一个大型的、可伸缩的、分布式的系统,有一些操作,在这样的系统中,有一点不确定的现象,被删除的东西既存在又不存在,同时删除请求正在通过系统传播。
虽然以下陈述不能直接证明上述断言适用于您正在采取的行动,但它是一个强有力的指标:
This action is idempotent.
http://docs.aws.amazon.com/sns/latest/api/API_DeleteEndpoint.html
可以重复幂等操作而不改变结果(比如将 0 加到一个整数上)。本质上,如果操作如文档所述是幂等的,那么成功响应并不意味着 "it has been deleted," 它意味着 "you are authorized to delete this, and it will be deleted, if it hasn't been already."
因此,您的解决方法是使用指数退避计时器在循环中进行轮询,直到获得预期的空结果,如果您需要在继续之前知道它真的消失了。这实际上并不能保证它将在整个系统范围内完全消失,因此您可能仍然会发生冲突,尽管可能性较小。
"Guarantee" 对于分布式系统来说是一个困难的命题,除非它们对所有操作都具有即时一致性,但通常情况并非如此,因为即时一致性通常与可伸缩性不一致。
如何确保在创建具有相同令牌的新 SNS 应用程序端点之前安全删除我的 SNS 应用程序端点?我有一个带有 ProgressListner 的删除方法,但是当我检查已删除的端点时,它仍然存在很短的时间。
我预计在收到 CLIENT_REQUEST_SUCCESS_EVENT 时删除已 100% 完成。我使用的是 AmazonSNSClient 而不是 AmazonSNSAsyncClient
public void deleteEndpoint(final String applicationArn, final String token) {
LOG.fine(String.format("Deleting endpoint by token for appArn=%s, token=%s", applicationArn, token));
Endpoint endpoint = findEndpointByToken(applicationArn, token);
if (endpoint != null) {
DeleteEndpointRequest der = new DeleteEndpointRequest().withEndpointArn(endpoint.getEndpointArn());
der.withGeneralProgressListener(new ProgressListener() {
public void progressChanged(ProgressEvent event) {
ProgressEventType eventType = event.getEventType();
System.out.println(eventType);
if (eventType.equals(ProgressEventType.CLIENT_REQUEST_SUCCESS_EVENT)) {
Endpoint exists = findEndpointByToken(applicationArn, token);
//This I expect this to be null but its only null after a few seconds
}
}
});
LOG.info(String.format("Deleted endpoint by token for appArn=%s, token=%s", applicationArn, token));
}
}
事件的输出是
CLIENT_REQUEST_STARTED_EVENT
HTTP_REQUEST_STARTED_EVENT
HTTP_REQUEST_COMPLETED_EVENT
RESPONSE_CONTENT_LENGTH_EVENT
HTTP_RESPONSE_STARTED_EVENT
RESPONSE_BYTE_TRANSFER_EVENT
HTTP_RESPONSE_COMPLETED_EVENT
CLIENT_REQUEST_SUCCESS_EVENT
SNS是一个大型的、可伸缩的、分布式的系统,有一些操作,在这样的系统中,有一点不确定的现象,被删除的东西既存在又不存在,同时删除请求正在通过系统传播。
虽然以下陈述不能直接证明上述断言适用于您正在采取的行动,但它是一个强有力的指标:
This action is idempotent.
http://docs.aws.amazon.com/sns/latest/api/API_DeleteEndpoint.html
可以重复幂等操作而不改变结果(比如将 0 加到一个整数上)。本质上,如果操作如文档所述是幂等的,那么成功响应并不意味着 "it has been deleted," 它意味着 "you are authorized to delete this, and it will be deleted, if it hasn't been already."
因此,您的解决方法是使用指数退避计时器在循环中进行轮询,直到获得预期的空结果,如果您需要在继续之前知道它真的消失了。这实际上并不能保证它将在整个系统范围内完全消失,因此您可能仍然会发生冲突,尽管可能性较小。
"Guarantee" 对于分布式系统来说是一个困难的命题,除非它们对所有操作都具有即时一致性,但通常情况并非如此,因为即时一致性通常与可伸缩性不一致。