2017-05-05 3 views
1

Play 2.5 애플리케이션에서 한 트랜잭션 내의 데이터베이스에서 많은 양의 데이터를 읽고 클라이언트에 HTTP 응답으로 전송하는 서비스를 만들어야합니다.청크 응답에 대한 OutputStream

느린 네트워크 속도로 인해 데이터베이스에서 데이터를 가져 오는 데 사용 된 DB 연결이 너무 오래 사용 될 수 있으므로 역압을 사용하지 않으려합니다.

현재 구현은 먼저 데이터를 임시 버퍼 (너무 많은 데이터 인 경우 메모리 또는 파일)로 추출하고 DB 연결을 해제하고 데이터와 함께 Ok 응답을 반환합니다.

단점은 데이터가 데이터베이스에서 완전히 추출 될 때 클라이언트에 데이터를 보내는 것이 먼저 시작된다는 것입니다.

소스의 일종으로 데이터를 추출하는 것이 더 좋을 것이라고 생각합니다. 예를 들어 10kB 이상인 경우 모든 데이터를 메모리와 디스크에 버퍼링하지만 데이터를 청크 응답에 즉시 제공합니다.

나는이를 구현할 계획,하지만 난 바로 그것을 얻을 어떤 힌트, 지침, 기존의 공개 구현을 위해 사전에 등

감사를 차단, 멀티 스레딩에 대한 미묘한 버그를 구현하지 않습니다 두렵다. ..

답변

1

파일을 중간 버퍼로 사용하는 경우 "모든 데이터를 버퍼링하는 소스"역할을 할 수 있습니다. 파일을 동시에 쓰고 읽을 수 있습니다 (이것은 윈도우 시스템에 대해서는 확실하지 않습니다). 따라서 데이터베이스 데이터를 사용하여 파일에 쓰고 파일 데이터를 사용하여 클라이언트에 응답 할 수 있습니다.

요청이 들어 오면 데이터베이스 쿼리를 시작하고 append mode의 출력을 버퍼 파일로 보냅니다.

쓰기가 진행되는 동안 읽기 모드에서 파일로 제공되는 엔티티로 클라이언트에 http 응답을 동시에 보냅니다.

"멀티 스레딩, 차단 등과 관련하여 미묘한 버그"에 대해 걱정할 필요가 없습니다. 왜냐하면 당신은 OS와 파일 시스템이 당신을 위해 대부분의 일을하도록하기 때문입니다.

+0

Thansk. 나는 그 접근법을 시도 할 것이다. 그래도 여전히 이상하지 않습니다. 소량의 데이터 만 있으면 모든 것을 메모리에 보관하고 싶습니다. 또 다른 질문은 생산자가 소비자보다 느리고 현재 생산자가 모든 데이터를 기록하기 전에 파일의 끝에 도달하면 어떻게 될까요? –

+0

@ GregorRaýman 여러분 환영합니다. "적은 양의 데이터가있는 경우"와 관련하여 이것은 "많은 양의 데이터를 읽는 서비스를 만들어야합니다."라는 원래의 질문과 모순됩니다. 생산물이 소비자보다 느리다면 파일 판독기가 EOF에 도달 할 때까지 계속됩니다 (이것이 모든 파일 판독기가 최저 수준의 io 스트림을 갖는 이유입니다). –

+0

라몬에게 감사 드려요, 나는 그 접근법을 시도 할 것입니다. 내가 가진 문제는 적은 양의 데이터 (수 kB) 또는 많은 양의 데이터 (수십 MB)가 있는지 여부를 미리 알지 못한다는 것입니다. 이것이 현재 메모리에 데이터를 버퍼링하고 구성된 임계 값을 오버플로 할 때 파일로 전환하기 시작하는 이유입니다. 대기 시간 때문에, 그리고 많은 양의 데이터가 있더라도 소비자가 충분히 빠르면 파일을 완전히 피할 수 있기 때문에 이것은 이상적이지 않습니다. –