비동기 함수

비동기 함수란 동기함수와는 다르게 호출시점에서 실행결과를 기다리지 않아도 되는 함수입니다.

  • 동기함수
    동기 함수의 경우 함수 호출 시 해당 함수 호출에 대한 결과가 나올 때 까지 동기 함수를 호출한 쓰레드의 동작이 사실상 중지하게 됩니다.
    이 때 사용자는 프로그램이 멈춘 것 같은 느낌을 받을 수 있습니다.

  • 비동기함수
    비동기 함수의 경우 비동기 함수를 호출한 쓰레드에서 해당 함수 호출에 대한 결과를 기다리지 않고 바로 다음 작업을 수행할 수 있습니다.
    이 때 로딩같은 작업을 수행하면 사용자에게 프로그램이 멈춘 것이 아닌 데이터를 로딩 혹은 저장 중이라는 경험을 제공할 수 있습니다.

뒤끝 비동기 함수 사용 시 주의사항

동기 함수, 비동기 함수 관계없이 서버로 요청을 보내기 위해 함수를 호출하면 즉시 서버로 요청이 보내지지 않습니다.
모든 요청이 OS 스케줄러에 따라 OS가 여건이 될 때 서버로 요청이 보내집니다.
다만 이 시간은 매우 짧아 바로 함수 호출 즉시 서버로 요청이 가는 것처럼 보입니다.

이 때 여러 개의 비동기 함수를 거의 동시에(for루프 등) 호출하는 경우 서버로 보내는 요청이 OS 스케줄러에 따라 대기하고 있다가, 대기하고 있던 요청들이 한번에 서버로 보내질 수 있습니다.

이 경우 서버에서는 모든 요청에 대해 처리를 한 뒤 응답을 하기 때문에 다양한 에러상황이 발생할 수 있습니다.

비동기 함수를 여러 개 호출하는 상황은 아래와 같습니다.

  • 비동기 함수를 한번에 여러 개 호출하는 경우
  • 비동기 함수를 호출한 후 해당 호출에 대한 응답이 오기 전에 다시 비동기 함수를 요청한 경우
  • 비동기 함수 내부에서 비동기 함수를 연속적으로 호출하는 경우
  • 함수에서 중복으로 사용되는 값이 존재하는 비동기 함수를 한번에 여러 개 혹은 연속적으로 호출하는 경우
    (동일 row 수정 시도 등)

비동기 함수를 여러 개 호출하는 경우 아래와 같은 상황이 발생할 수 있습니다.

  • 함수 호출에 대한 응답이 늦어질 수 있습니다.
  • 호출에 대한 응답이 늦어져 statusCode : 408 / message : timeout error가 리턴될 수 있습니다.
  • 2개 이상의 요청을 보냈을 때 1번째 요청에서 사용한 값이 2번째 요청에서도 필요한 경우가 발생했을 때 최종적 읽기 일관성이 보장이 안될 수 있습니다.
    • statusCode : 500 / message : Request failed with status code 400가 리턴될 수 있습니다.
    • 첫번째 요청은 성공하지만 두번째 요청은 실패하거나 혹은 두번째 요청은 성공하지만 첫번째 요청은 실패하는 경우가 발생할 수 있습니다.

한번에 여러 개의 비동기 함수 호출하기

한번에 여러 개의 비동기 함수를 원하는 시점에 호출하고 싶을 때는 SendQueue를 활용해보세요.

  • rpg 게임같이 유저가 계속 아이템을 사용하고, 획득하는 과정에서 동일한 테이블의 동일한 colum을 반복적으로(매우 짧은 간격으로) update 비동기 함수를 호출할 경우 에러가 발생하게 됩니다.
  • 이 때 제일 먼저 보낸 요청만 처리되고, 뒤에 보낸 데이터가 처리되지 않아 유저가 데이터가 롤백된 것같은 경험을 할 수 있습니다.
  • 해당 경우 아래 SendQueue를 사용할 경우 개선이 가능하나, 근본적으로는 DB 구조 자체를 바꿔야 개선이 가능합니다. 해당 문서를 참고해주세요