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

INTERNAL: make lop piped operations process synchronously #795

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

oliviarla
Copy link
Collaborator

๐Ÿ”— Related Issue

โŒจ๏ธ What I did

  • 500๊ฐœ ์•„์ดํ…œ ๋‹จ์œ„๋กœ Operation ๊ฐ์ฒด๋ฅผ ๋‚˜๋ˆ„์–ด ๋น„๋™๊ธฐ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋˜ ๊ฒƒ์„ ๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ๋ณด๋‚ด์–ด Arcus ์„œ๋ฒ„์— ๊ณผ๋„ํ•œ ๋ถ€ํ•˜๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ณ , ์‹คํŒจ ์‹œ ๋‹ค์Œ Operation์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
    • ๋งŒ์•ฝ CLIENT_ERROR, SERVER_ERROR ์‹คํŒจ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๊ทธ ์ฆ‰์‹œ latch.countdown์„ ํ˜ธ์ถœํ•ด ๋”์ด์ƒ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    • OVERFLOWED, OUT_OF_RANGE ๊ฐ™์€ ์‹คํŒจ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ดํ›„์˜ item์— ๋Œ€ํ•ด CANCELLED ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ธฐ์กด์— asyncLopPipedInsert์—์„œ ์ž…๋ ฅ๋ฐ›์€ valueList ์ˆœ์„œ๋Œ€๋กœ ์ €์žฅํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๊ณ  ์ด๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ €์žฅํ•˜๋„๋ก ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์‹œ๋ฒ”์ ์œผ๋กœ Lop Piped Insert์—๋งŒ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • future๋ฅผ ํ†ตํ•œ ๋น„๋™๊ธฐ ์ˆ˜ํ–‰์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์„œ๋“œ๋ช…์€ ๊ทธ๋Œ€๋กœ ๋‘๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

oliviarla referenced this pull request in oliviarla/arcus-java-client Aug 19, 2024
@jhpark816 jhpark816 removed their request for review August 19, 2024 06:42
@oliviarla oliviarla requested review from jhpark816 and removed request for jhpark816 August 19, 2024 06:43
@oliviarla oliviarla self-assigned this Aug 19, 2024
uhm0311
uhm0311 previously approved these changes Aug 27, 2024
Copy link
Collaborator

@jhpark816 jhpark816 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ผ๋ถ€ ๋ฆฌ๋ทฐ

src/main/java/net/spy/memcached/ArcusClient.java Outdated Show resolved Hide resolved
|| rv.getOperationStatus().getResponse() == CollectionResponse.CANCELED) {
// countdown if this is last op
latch.countDown();
} else if (!rv.getOperationStatus().isSuccess()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rv.getOperationStatus().isSuccess() ์กฐ๊ฑด์œผ๋กœ next ์—ฐ์‚ฐ ์ˆ˜ํ–‰ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
์ด ๋ถ€๋ถ„์— ๋Œ€ํ•ด offline ๋…ผ์˜ํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ด€๋ จ ์‚ฌํ•ญ์„ ์ข€ ๋” ์ž์„ธํ•˜๊ฒŒ ์ ์œผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • PIPE_ERROR ์‘๋‹ต์ด ์˜จ ๊ฒฝ์šฐ
    • ํ˜„์žฌ์˜ piped ์—ฐ์‚ฐ์—์„œ PIPE_ERROR๋กœ ์ธํ•ด ์•„์˜ˆ ์ˆ˜ํ–‰๋˜์ง€ item ์—ฐ์‚ฐ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์ด ๊ฒฝ์šฐ, ํ˜„์žฌ failed Result์— ๊ฒฐ๊ณผ๋ฅผ ๋‹ด์ง€ ์•Š๊ณ  ์žˆ์œผ๋ฏ€๋กœ, ์ด๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • PIPE_END ์‘๋‹ต์ด ์˜จ ๊ฒฝ์šฐ
    • ๊ฐœ๋ณ„ ์—ฐ์‚ฐ์— ๋Œ€ํ•ด NOT_FOUND, ELEMENT_EXISTS, OVERFLOWED, OUT_OF_RANGE, TYPE_MISMATCH, BKEY_MISMATCH ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • B+Tree collection์— ๋Œ€ํ•ด BKEY_MISMATCH ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ, ์ฃผ์–ด์ง„ element๋งŒ insert ์‹คํŒจํ•˜๊ณ  ๋‚˜๋จธ์ง„ ์„ฑ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, next ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋งž์ง€ ์•Š๋Š” ์ง€ ? ELEMENT_EXISTS ์˜ค๋ฅ˜๋„ ๋น„์Šทํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.
    • ๊ทธ ์™ธ์˜ ์˜ค๋ฅ˜์ธ ๊ฒฝ์šฐ๋Š” ์บ์‹œ ์„œ๋ฒ„์—์„œ ์ˆ˜ํ–‰์„ ์ค‘์ง€ํ•˜๊ณ , PIPE_ERROR ๋ฆฌํ„ดํ•ด์•ผ ํ•˜์ง€ ์•Š๋‚˜ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฒฐ๊ตญ, ์บ์‹œ ์„œ๋ฒ„ ๋™์ž‘ ๋ถ€๋ถ„๋„ ํ•จ๊ป˜ ๊ณ ๋ ค๋˜์–ด์•ผ ํ•˜์ง€ ์•Š๋‚˜ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

END ์‘๋‹ต์ด ์™”๊ณ  btree์ผ ๋•Œ BKEY_MISMATCH, map, set์ผ ๋•Œ ELEMENT_EXISTS๋งŒ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด ๋‹ค์Œ Operation ๋ณด๋‚ด๋Š” ๊ฒƒ์—๋Š” ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

PIPE_ERROR๊ฐ€ CLIENT_ERROR, SERVER_ERROR ๋กœ ์ธํ•ด ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ด failed result๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. PIPE_ERROR๊ฐ€ command/memory overflow ๋กœ ์ธํ•ด ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด ์—๋Ÿฌ๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ๋ชจ๋“  ์‘๋‹ต์„ ๊ธฐ์ค€์œผ๋กœ ์ „์ฒด ์„ฑ๊ณต/์‹คํŒจ ์—ฌ๋ถ€๋งŒ ํŒ๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ "PIPE_ERROR" ๋ผ๋Š” ์‘๋‹ต์ด ์™”๋Š”์ง€ future์—์„œ๋Š” ํ™•์ธํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, failed result์— ๊ฒฐ๊ณผ๋ฅผ ๋„ฃ์„ ํ•„์š”๋„ ์—†์Šต๋‹ˆ๋‹ค.

if (line.startsWith("END") || line.startsWith("PIPE_ERROR ")) {
/* ENABLE_MIGRATION if */
if (needRedirect()) {
transitionState(OperationState.REDIRECT);
return;
}
/* ENABLE_MIGRATION end */
cb.receivedStatus((successAll) ? END : FAILED_END);
transitionState(OperationState.COMPLETE);
} else if (line.startsWith("RESPONSE ")) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oliviarla

๊ธฐ์กด pipe ์ฒ˜๋ฆฌ์—๋„ ์ผ๋ถ€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • CLIENT_ERROR, SERVER_ERROR ๋“ฑ์˜ ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, java client๋Š” PIPE_ERROR ์‘๋‹ต๊นŒ์ง€ ์ฝ์ง€ ์•Š๋Š”๋‹ค.
    ๊ทธ๋Ÿฌ๋ฉด, ๋‹ค์Œ ์—ฐ์‚ฐ์—์„œ ์‘๋‹ต์„ ์ฝ์„ ์‹œ์— PIPE_ERROR ์‘๋‹ต์„ ๋ณด๊ฒŒ ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
    ๋Œ€๋žต ํ™•์ธํ•œ ์‚ฌํ•ญ์ด๋ผ, ์ด ๋ถ€๋ถ„์— ๊ด€ํ•œ ์ฝ”๋“œ๋Š” ์ง์ ‘ ํ™•์ธํ•ด ๋ณด๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.
  • ์•„๋ž˜ 2๊ฐ€์ง€ PIPE_ERROR์— ๋Œ€ํ•ด "END" ์‘๋‹ต์„ ๋ฐ›์€ ๊ฒฝ์šฐ์™€ ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    ์ฆ‰, ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•œ ์—ฐ์‚ฐ์ด ์กด์žฌํ•˜๋”๋ผ๋„ ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋œ ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
    • PIPE_ERROR command overflow
    • PIPE_ERROR memory overflow

์ด๋Ÿฌํ•œ pipe ์ฒ˜๋ฆฌ ์˜ค๋ฅ˜๋Š” ๋ณธ PR๊ณผ๋Š” ๋ณ„๋„๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜์ฃ ?
๊ฒ€ํ†  ๋ฐ”๋ž๋‹ˆ๋‹ค.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLIENT_ERROR, SERVER_ERROR ๋“ฑ์˜ ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, ๋ฐ”๋กœ OperationException์ด throw ๋ฉ๋‹ˆ๋‹ค.
์ด ์˜ˆ์™ธ๋ฅผ MemcachedConnection์—์„œ catchํ•˜์—ฌ ์—ฐ๊ฒฐ์„ ๋Š๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ ์—ฐ์‚ฐ์ด ์‘๋‹ต์„ ์ฝ์„ ์ˆ˜ ์—†์„ ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

} catch (OperationException e) {
qa.setupForAuth("operation exception"); // noop if !shouldAuth
getLogger().warn("Reconnection due to exception " +
"handling a memcached exception on %s.", qa, e);
lostConnection(qa, ReconnDelay.IMMEDIATE, "operation exception");

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PIPE_ERROR command/memory overflow ์˜ค๋ฅ˜ ์‹œ, ์ฒ˜๋ฆฌ๋˜์ง€ ๋ชปํ•œ ์—ฐ์‚ฐ์— ๋Œ€ํ•ด
๋ณธ PR ์ฒ˜๋Ÿผ CANCELED CollectionOperationStatus ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PIPE_ERROR command/memory overflow ์˜ค๋ฅ˜ ์‹œ, ์ฒ˜๋ฆฌ๋˜์ง€ ๋ชปํ•œ ์—ฐ์‚ฐ์— ๋Œ€ํ•ด
๋ณธ PR ์ฒ˜๋Ÿผ CANCELED CollectionOperationStatus ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

์œ„ ์‚ฌํ•ญ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด
์•„๋ž˜ ๋กœ์ง์—์„œ cb.receivedStatus() ํ˜ธ์ถœ ์‹œ์˜ ์ธ์ž ๊ฐ’์ด ์ˆ˜์ •๋˜์–ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

         if (line.startsWith("END") || line.startsWith("PIPE_ERROR ")) { 
	   /* ENABLE_MIGRATION if */ 
	   if (needRedirect()) { 
	     transitionState(OperationState.REDIRECT); 
	     return; 
	   } 
	   /* ENABLE_MIGRATION end */ 
	   cb.receivedStatus((successAll) ? END : FAILED_END); 
	   transitionState(OperationState.COMPLETE); 
	 } else if (line.startsWith("RESPONSE ")) { 

์•„๋ž˜์™€ ๊ฐ™์ด ํ˜ธ์ถœํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

	   cb.receivedStatus((index == count && successAll) ? END : FAILED_END); 

๋˜ํ•œ, ์•„๋ž˜ ๊ฒฝ์šฐ์— CENCEL ์ƒํƒœ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋กœ์ง๋„ ์ˆ˜์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

        if (!rv.getOperationStatus().isSuccess()) {
          rv.addEachResult(index + (idx * CollectionPipedInsert.MAX_PIPED_ITEM_COUNT),
                  new CollectionOperationStatus(false, "CANCELED", CollectionResponse.CANCELED));
          latch.countDown();
        } 

์œ„์™€ ๊ฐ™์ด ๋ณ€๊ฒฝ๋˜๋ฉด,
complete() ๋กœ์ง์—์„œ์˜ ๊ฒ€์‚ฌ ์ˆœ์„œ๋„ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์•„๋ž˜ ์กฐ๊ฑด์ด ๊ฐ€์žฅ ๋จผ์ € ๊ฒ€์‚ฌ๋˜์–ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

        if (!rv.getOperationStatus().isSuccess()) 

Copy link
Collaborator

@jhpark816 jhpark816 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋ฆฌ๋ทฐ ์™„๋ฃŒ

src/main/java/net/spy/memcached/ArcusClient.java Outdated Show resolved Hide resolved
src/main/java/net/spy/memcached/ArcusClient.java Outdated Show resolved Hide resolved
@oliviarla
Copy link
Collaborator Author

@jhpark816 ๋ฆฌ๋ทฐ ๋ฐ˜์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

@jhpark816
Copy link
Collaborator

@uhm0311 ๋ฆฌ๋ทฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@uhm0311
Copy link
Collaborator

uhm0311 commented Sep 23, 2024

@oliviarla

์ปจํ”Œ๋ฆญํŠธ ํ™•์ธํ•ด์ฃผ์„ธ์š”.

uhm0311
uhm0311 previously approved these changes Sep 23, 2024
@@ -145,6 +145,10 @@ assert getState() == OperationState.READING
/* ENABLE_MIGRATION end */
cb.receivedStatus((successAll) ? END : FAILED_END);
transitionState(OperationState.COMPLETE);
} else if (line.startsWith("PIPE_ERROR ")) {
// command flow / memory flow
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@namsic @uhm0311
์ œ ์ƒ๊ฐ์—๋Š” PIPE_ERROR memory overflow์ผ ๊ฒฝ์šฐ์—๋งŒ redirect ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™์€๋ฐ, ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์‹œ๋‚˜์š”?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PIPE_ERROR ์ข…๋ฅ˜๊ฐ€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PIPE_ERROR๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ข…๋ฅ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • PIPE_ERROR bad error : SERVER_ERROR / CLIENT_ERROR ๋ฐœ์ƒํ•˜์—ฌ ์˜ˆ์™ธ๊ฐ€ ๋ฐ˜ํ™˜๋œ ์ƒํ™ฉ์ด๋ฉฐ, ํ•ด๋‹น ๋‘ ์ผ€์ด์Šค๋Š” ํ˜„์žฌ ์ฒ˜๋ฆฌ์ค‘์— exception์ด throw๋˜๋ฏ€๋กœ ์ด ์ฝ”๋“œ์— ๋„๋‹ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • PIPE_ERROR command overflow : pipelining ๊ฐ€๋Šฅํ•œ command์˜ ์ตœ๋Œ€ ๊ฐœ์ˆ˜๋ฅผ ๋„˜์–ด์„  ์š”์ฒญ์ด ๋“ค์–ด์™€ ์˜ˆ์™ธ๊ฐ€ ๋ฐ˜ํ™˜๋œ ์ƒํ™ฉ
  • PIPE_ERROR memory overflow : pipelining ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์ด ๋ถ€์กฑํ•˜๊ฒŒ ๋˜์–ด ํŒŒ์ดํ”„๋ผ์ธ ์ˆ˜ํ–‰์„ ๋ฉˆ์ถ”๊ณ  ์˜ˆ์™ธ๊ฐ€ ๋ฐ˜ํ™˜๋œ ์ƒํ™ฉ

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

command overflow์™€ memory overflow์ผ ๋•Œ Redirect๋ฅผ ํ•˜์ง€ ์•Š๋Š” ์ด์œ ์™€ ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

command overflow์ผ ๋•Œ๋Š” ํ•ด๋‹น operation์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” pipe ๋ช…๋ น์–ด์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋™์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— redirectํ•˜์—ฌ ๋˜‘๊ฐ™์€ ๋ช…๋ น์„ ๋ณด๋‚ด๋ฉด ์‹คํŒจํ•˜๋ฏ€๋กœ redirectํ•  ํ•„์š”์„ฑ์ด ์—†์–ด๋ณด์ž…๋‹ˆ๋‹ค.
memory overflow์ผ ๋•Œ๋Š” ํ•ด๋‹น ์บ์‹œ ๋…ธ๋“œ์— memory ์šฉ๋Ÿ‰์ด ๋ถ€์กฑํ–ˆ๋˜ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ redirect๋˜์—ˆ์„ ๋•Œ ์„ฑ๊ณตํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ redirect ์ฒ˜๋ฆฌํ•˜๋ฉด ๋  ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ฐธ๊ณ  ์‚ฌํ•ญ์œผ๋กœ, ํ˜„์žฌ ์„œ๋ฒ„ ๊ตฌํ˜„ ๊ธฐ์ค€

  • single key pipe์—์„œ NOT_MY_KEY์™€ PIPE_ERROR๋ฅผ ํ•จ๊ป˜ ์‘๋‹ตํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • multi key pipe์—์„œ๋Š” NOT_MY_KEY์™€ PIPE_ERROR๊ฐ€ ํ•จ๊ป˜ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋งŒ migration ๊ด€๋ จ ๊ตฌํ˜„์€ ์•„์ง ์™„์ „ํžˆ ์ •๋ฆฌ๋œ ์ƒํƒœ๋Š” ์•„๋‹ˆ์–ด์„œ ์ถ”ํ›„ ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์€ ์žˆ์–ด ๋ณด์ž…๋‹ˆ๋‹ค.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

single key pipe์—์„œ NOT_MY_KEY์™€ PIPE_ERROR๋ฅผ ํ•จ๊ป˜ ์‘๋‹ตํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์™œ ๊ทธ๋Ÿฐ์ง€ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ์ฃ .

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์™œ ๊ทธ๋Ÿฐ์ง€ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ์ฃ .

์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด ๋ณด๋‹ˆ, NOT_MY_KEY ๋ฐœ์ƒ ์ดํ›„ invalid command ์ˆ˜์‹ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š”
NOT_MY_KEY + CLIENT_ERROR + PIPE_ERROR bad error ์‘๋‹ต์ด ๊ฐ€๋Šฅํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.

๊ทธ ์™ธ์— ์ •์ƒ์ ์ธ ๋ช…๋ น์œผ๋กœ ๊ตฌ์„ฑ๋œ single key pipe์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

https://github.com/jam2in/arcus-memcached-EE/wiki/Response-format

  1. pipe ์ฒ˜๋ฆฌ ์ค‘ NOT_MY_KEY ๋ฐœ์ƒํ•˜๋ฉด response buffer์— NOT_MY_KEY ์‘๋‹ต์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

    • ๋งŒ์•ฝ ์ด ์‘๋‹ต์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด, NOT_MY_KEY ์‘๋‹ต ๋Œ€์‹ 
      PIPE_ERROR ์‘๋‹ต์ด ์ถ”๊ฐ€๋˜๋ฉฐ pipe ์ข…๋ฃŒํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ต์„ ๋Œ๋ ค์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  2. single key pipe ๋ช…๋ น์—์„œ ์ง์ „ ๋ช…๋ น์ด NOT_MY_KEY ๋ฐœ์ƒํ–ˆ์œผ๋ฉด ํ˜„์žฌ ๋ช…๋ น์€ swallow(skip) ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

    • ์ˆ˜ํ–‰ํ•˜๋”๋ผ๋„ NOT_MY_KEY ๋ฐœ์ƒํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
  3. NOT_MY_KEY 1ํšŒ ๋ฐœ์ƒ ์ดํ›„ ๋ชจ๋“  ๋ช…๋ น์ด swallow ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ
    PIPE_ERROR๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ(cmd_ovfl, mem_ovfl, ERROR)์ด ์—†๊ณ ,
    ๋งˆ์ง€๋ง‰ ๋ช…๋ น๊นŒ์ง€ swallow ์ฒ˜๋ฆฌ๋œ ํ›„ END์™€ ํ•จ๊ป˜ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ต ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLIENT_ERROR ์ด๋”๋ผ๋„ PIPE_ERROR๊นŒ์ง€ ์ฝ๋„๋ก ์ˆ˜์ •ํ•œ๋‹ค๋ฉด,
PIPE_ERROR์ด๋”๋ผ๋„ redirect ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ, CLIENT_ERROR ์ด๋”๋ผ๋„ PIPE_ERROR๊นŒ์ง€ ์ฝ๊ฒŒ ํ•˜๋Š” ์ž‘์—…์„ ๋จผ์ € ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

command overflow์ผ ๋•Œ๋Š” ํ•ด๋‹น operation์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” pipe ๋ช…๋ น์–ด์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋™์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— redirectํ•˜์—ฌ ๋˜‘๊ฐ™์€ ๋ช…๋ น์„ ๋ณด๋‚ด๋ฉด ์‹คํŒจํ•˜๋ฏ€๋กœ redirectํ•  ํ•„์š”์„ฑ์ด ์—†์–ด๋ณด์ž…๋‹ˆ๋‹ค.
memory overflow์ผ ๋•Œ๋Š” ํ•ด๋‹น ์บ์‹œ ๋…ธ๋“œ์— memory ์šฉ๋Ÿ‰์ด ๋ถ€์กฑํ–ˆ๋˜ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ redirect๋˜์—ˆ์„ ๋•Œ ์„ฑ๊ณตํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ redirect ์ฒ˜๋ฆฌํ•˜๋ฉด ๋  ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด์šฉ์— ๋Œ€ํ•œ ์ฝ”๋ฉ˜ํŠธ์ž…๋‹ˆ๋‹ค.

  • command overflow์—์„œ redirectํ•˜๋ฉด, ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ์—ฐ์‚ฐ๋งŒ ๋ณด๋‚ด๋ฏ€๋กœ ํ•ด๋‹น ์—ฐ์‚ฐ๋“ค์€ ์„ฑ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • memory overflow์—์„œ rediretํ•˜๋Š” ์ด์œ ๋Š” ์ผ๋ถ€ ์—ฐ์‚ฐ์ด ์ฒ˜๋ฆฌ๋˜๊ธฐ ์ „์— ํ•ด๋‹น key๊ฐ€ ๋‹ค๋ฅธ node๋กœ ์ด์ „ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋ฉฐ, ์ฒ˜๋ฆฌ๋˜์ง€ ๋ชปํ•œ ์—ฐ์‚ฐ๋งŒ์„ ์ด์ „๋œ node๋กœ ๋ณด๋‚ด์–ด ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค๋ฉด command overflow๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ œ ์ƒ๊ฐ์—๋Š” command overflow๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด redirectํ•˜์ง€ ์•Š๊ณ  ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์ƒํ™ฉ์ž„์„ ์•Œ๋ฆฌ๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

memory overflow์— ๋Œ€ํ•ด์„œ๋Š” ๋ง์”€ํ•˜์‹  ์‚ฌํ•ญ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

Copy link
Collaborator

@jhpark816 jhpark816 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋ฆฌ๋ทฐ ์™„๋ฃŒ

src/main/java/net/spy/memcached/ArcusClient.java Outdated Show resolved Hide resolved
latch.countDown();
} else if (!rv.getOperationStatus().isSuccess()) {
// If this operation failed, remaining subsequent operation
// should not be added and should be marked as cancelled.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

complete() ๋กœ์ง์„ ์™„๋ฒฝํ•˜๊ฒŒ ๋งŒ๋“ค๋ ค๋ฉด,
PIPE_ERROR์ด๋”๋ผ๋„ ๋ชจ๋“  ์‘๋‹ต์„ ์ฝ์–ด๋‚ด๋Š” ๊ธฐ๋Šฅ์ด ๋จผ์ € ๊ตฌํ˜„๋˜์–ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ์ด์Šˆ๋กœ ์˜ฌ๋ฆฌ๊ณ  ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

|| rv.getOperationStatus().getResponse() == CollectionResponse.CANCELED) {
// countdown if this is last op
latch.countDown();
} else if (!rv.getOperationStatus().isSuccess()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PIPE_ERROR command/memory overflow ์˜ค๋ฅ˜ ์‹œ, ์ฒ˜๋ฆฌ๋˜์ง€ ๋ชปํ•œ ์—ฐ์‚ฐ์— ๋Œ€ํ•ด
๋ณธ PR ์ฒ˜๋Ÿผ CANCELED CollectionOperationStatus ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

์œ„ ์‚ฌํ•ญ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด
์•„๋ž˜ ๋กœ์ง์—์„œ cb.receivedStatus() ํ˜ธ์ถœ ์‹œ์˜ ์ธ์ž ๊ฐ’์ด ์ˆ˜์ •๋˜์–ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

         if (line.startsWith("END") || line.startsWith("PIPE_ERROR ")) { 
	   /* ENABLE_MIGRATION if */ 
	   if (needRedirect()) { 
	     transitionState(OperationState.REDIRECT); 
	     return; 
	   } 
	   /* ENABLE_MIGRATION end */ 
	   cb.receivedStatus((successAll) ? END : FAILED_END); 
	   transitionState(OperationState.COMPLETE); 
	 } else if (line.startsWith("RESPONSE ")) { 

์•„๋ž˜์™€ ๊ฐ™์ด ํ˜ธ์ถœํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

	   cb.receivedStatus((index == count && successAll) ? END : FAILED_END); 

๋˜ํ•œ, ์•„๋ž˜ ๊ฒฝ์šฐ์— CENCEL ์ƒํƒœ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋กœ์ง๋„ ์ˆ˜์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

        if (!rv.getOperationStatus().isSuccess()) {
          rv.addEachResult(index + (idx * CollectionPipedInsert.MAX_PIPED_ITEM_COUNT),
                  new CollectionOperationStatus(false, "CANCELED", CollectionResponse.CANCELED));
          latch.countDown();
        } 

์œ„์™€ ๊ฐ™์ด ๋ณ€๊ฒฝ๋˜๋ฉด,
complete() ๋กœ์ง์—์„œ์˜ ๊ฒ€์‚ฌ ์ˆœ์„œ๋„ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์•„๋ž˜ ์กฐ๊ฑด์ด ๊ฐ€์žฅ ๋จผ์ € ๊ฒ€์‚ฌ๋˜์–ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

        if (!rv.getOperationStatus().isSuccess()) 

}
}
return false;
return operationStatus.get().getResponse() == CollectionResponse.CANCELED;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋งˆ์ง€๋ง‰ op์— ๋Œ€ํ•ด isCancelled() ํ˜ธ์ถœํ•ด์•ผ ํ•˜์ง€ ์•Š๋‚˜์š”?

return ops.get(ops.size() - 1).isCancelled();

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์‚ฌ์šฉ์ž๊ฐ€ future.cancel์„ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ๋‚ด๋ถ€์ ์œผ๋กœ op.cancel์ด ํ˜ธ์ถœ๋˜๋ฉด BaseOperationImpl์˜ cancel ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
ํ•ด๋‹น cancel ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ๋Š” wasCancelled ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋Š” ์ž์‹ ํด๋ž˜์Šค์ธCollectionPipedInsertOperationImpl์— ๊ตฌํ˜„๋˜์–ด ์žˆ๊ณ , receivedStatus์— ์˜ํ•ด future์˜ ์ƒํƒœ์— ์“ฐ์ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ operationStatus๋งŒ์œผ๋กœ๋„ cancel ์—ฌ๋ถ€๋ฅผ ํ™•์ธ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

public final boolean cancel(String cause) {
if (callbacked.compareAndSet(false, true)) {
cancelled = true;
if (handlingNode != null) {
cause += " @ " + handlingNode.getNodeName();
}
cancelCause = "Cancelled (" + cause + ")";
wasCancelled();
callback.complete();
return true;
}
return false;
}

@Override
protected void wasCancelled() {
getCallback().receivedStatus(STORE_CANCELED);
}

@@ -145,6 +145,10 @@ assert getState() == OperationState.READING
/* ENABLE_MIGRATION end */
cb.receivedStatus((successAll) ? END : FAILED_END);
transitionState(OperationState.COMPLETE);
} else if (line.startsWith("PIPE_ERROR ")) {
// command flow / memory flow
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLIENT_ERROR ์ด๋”๋ผ๋„ PIPE_ERROR๊นŒ์ง€ ์ฝ๋„๋ก ์ˆ˜์ •ํ•œ๋‹ค๋ฉด,
PIPE_ERROR์ด๋”๋ผ๋„ redirect ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ, CLIENT_ERROR ์ด๋”๋ผ๋„ PIPE_ERROR๊นŒ์ง€ ์ฝ๊ฒŒ ํ•˜๋Š” ์ž‘์—…์„ ๋จผ์ € ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

command overflow์ผ ๋•Œ๋Š” ํ•ด๋‹น operation์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” pipe ๋ช…๋ น์–ด์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋™์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— redirectํ•˜์—ฌ ๋˜‘๊ฐ™์€ ๋ช…๋ น์„ ๋ณด๋‚ด๋ฉด ์‹คํŒจํ•˜๋ฏ€๋กœ redirectํ•  ํ•„์š”์„ฑ์ด ์—†์–ด๋ณด์ž…๋‹ˆ๋‹ค.
memory overflow์ผ ๋•Œ๋Š” ํ•ด๋‹น ์บ์‹œ ๋…ธ๋“œ์— memory ์šฉ๋Ÿ‰์ด ๋ถ€์กฑํ–ˆ๋˜ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ redirect๋˜์—ˆ์„ ๋•Œ ์„ฑ๊ณตํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ redirect ์ฒ˜๋ฆฌํ•˜๋ฉด ๋  ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด์šฉ์— ๋Œ€ํ•œ ์ฝ”๋ฉ˜ํŠธ์ž…๋‹ˆ๋‹ค.

  • command overflow์—์„œ redirectํ•˜๋ฉด, ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ์—ฐ์‚ฐ๋งŒ ๋ณด๋‚ด๋ฏ€๋กœ ํ•ด๋‹น ์—ฐ์‚ฐ๋“ค์€ ์„ฑ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • memory overflow์—์„œ rediretํ•˜๋Š” ์ด์œ ๋Š” ์ผ๋ถ€ ์—ฐ์‚ฐ์ด ์ฒ˜๋ฆฌ๋˜๊ธฐ ์ „์— ํ•ด๋‹น key๊ฐ€ ๋‹ค๋ฅธ node๋กœ ์ด์ „ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋ฉฐ, ์ฒ˜๋ฆฌ๋˜์ง€ ๋ชปํ•œ ์—ฐ์‚ฐ๋งŒ์„ ์ด์ „๋œ node๋กœ ๋ณด๋‚ด์–ด ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

throw new CheckedOperationTimeoutException(duration, unit, elapsed, timedOutOps);
}
Operation lastOp = ops.get(ops.size() - 1);
if (!latch.await(duration, unit) && lastOp.getState() != OperationState.COMPLETE) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

latch.await() ํ˜ธ์ถœ ์ „์— lastOp ๊ฐ์ฒด๋ฅผ ๋ฏธ๋ฆฌ ๊ตฌํ•ด๋‘๋Š” ๊ฒƒ์ด ์ด์ƒํ•ฉ๋‹ˆ๋‹ค.
latch.await() ๋™์•ˆ์—๋„ ์ƒˆ๋กœ์šด op๊ฐ€ ์ƒ์„ฑ๋˜์–ด ๋“ฑ๋ก๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , lastOp๊ฐ€ ์‹ค์ œ future์— ๋“ฑ๋ก๋œ ๋งˆ์ง€๋ง‰ op๊ฐ€ ์•„๋‹ˆ๋ผ
์‹ค์ œ ์š”์ฒญํ•ด์•ผ ํ•  ๋งˆ์ง€๋ง‰ op์ด์–ด์•ผ ํ•˜์ง€ ์•Š๋Š”๊ฐ€์š”?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ทธ๋ฆฌ๊ณ , lastOp๊ฐ€ ์‹ค์ œ future์— ๋“ฑ๋ก๋œ ๋งˆ์ง€๋ง‰ op๊ฐ€ ์•„๋‹ˆ๋ผ
์‹ค์ œ ์š”์ฒญํ•ด์•ผ ํ•  ๋งˆ์ง€๋ง‰ op์ด์–ด์•ผ ํ•˜์ง€ ์•Š๋Š”๊ฐ€์š”?

์—ฌ๋Ÿฌ Op ๊ฐ์ฒด ์—ฐ์‚ฐ ์ˆ˜ํ–‰ ์ค‘ ํ•˜๋‚˜์˜ Op์—์„œ ์˜ˆ์™ธ๋‚˜ ์ž˜๋ชป๋œ ์‘๋‹ต์ด ๋ฐœ์ƒํ•˜๋ฉด future์— ๋‹ค์Œ Op๋ฅผ ๋„ฃ์ง€ ์•Š๊ณ  latch๋ฅผ countdown์‹œํ‚ต๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ future์—์„œ๋Š” ์‹ค์ œ ์š”์ฒญํ•ด์•ผ ํ•  ๋งˆ์ง€๋ง‰ Op๋ฅผ ํ™•์ธํ•  ํ•„์š” ์—†์ด ์‹คํ–‰๋˜์—ˆ๋˜ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ Op๋งŒ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

Successfully merging this pull request may close these issues.

4 participants