-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chunk detection based on response format (#59)
This introduces `AbstractChunkReader` and adds a few chunk readers with different chunk detection strategies. Also includes some auto selection heuristics based on detected response format and ability to specify a chunk reader at `Ctx` and `Client` levels. Chunk readers available: - `LineChunkReader`: Chunks delimited by newline. This was the only available strategy earlier. It is now the default when the response type is detected to be not of `OpenAPI.APIModel` type. - `JSONChunkReader`: Each chunk is a JSON. Whitespaces between JSONs are ignored. This is now the default when the response type is detected to be a `OpenAPI.APIModel`. - `RFC7464ChunkReader`: A reader based on [RFC 7464](https://www.rfc-editor.org/rfc/rfc7464.html). Available for use by overriding through `Client` or `Ctx`. The `Client` and `Ctx` constructors take an additional `chunk_reader_type` keyword parameter. This can be one of `OpenAPI.Clients.LineChunkReader`, `OpenAPI.Clients.JSONChunkReader` or `OpenAPI.Clients.RFC7464ChunkReader`. If not specified, then the type is automatically determined based on the return type of the API call.
- Loading branch information
Showing
3 changed files
with
271 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
module ChunkReaderTests | ||
using Test | ||
using JSON | ||
using OpenAPI | ||
using OpenAPI.Clients: AbstractChunkReader, JSONChunkReader, LineChunkReader, RFC7464ChunkReader | ||
|
||
function linechunk1() | ||
buff = Base.BufferStream() | ||
reader = LineChunkReader(buff) | ||
results = String[] | ||
readertask = @async begin | ||
for line in reader | ||
push!(results, String(line)) | ||
end | ||
end | ||
write(buff, "hello\nworld\n") | ||
write(buff, "goodbye\n") | ||
close(buff) | ||
wait(readertask) | ||
@test results == ["hello", "world", "goodbye"] | ||
end | ||
|
||
function linechunk2() | ||
buff = Base.BufferStream() | ||
reader = LineChunkReader(buff) | ||
results = String[] | ||
readertask = @async begin | ||
for line in reader | ||
push!(results, String(line)) | ||
end | ||
end | ||
write(buff, "\nhello\nworld\n") | ||
write(buff, "goodbye\n") | ||
close(buff) | ||
wait(readertask) | ||
@test results == ["", "hello", "world", "goodbye"] | ||
end | ||
|
||
function linechunk3() | ||
buff = Base.BufferStream() | ||
reader = LineChunkReader(buff) | ||
results = String[] | ||
readertask = @async begin | ||
for line in reader | ||
push!(results, String(line)) | ||
end | ||
end | ||
write(buff, "hello\nworld\n") | ||
write(buff, "goodbye") | ||
close(buff) | ||
wait(readertask) | ||
@test results == ["hello", "world", "goodbye"] | ||
end | ||
|
||
function jsonchunk1() | ||
buff = Base.BufferStream() | ||
reader = JSONChunkReader(buff) | ||
results = String[] | ||
readertask = @async begin | ||
for json in reader | ||
push!(results, String(json)) | ||
end | ||
end | ||
|
||
write(buff, "{\"hello\": \"world\"}") | ||
write(buff, "{\"hello\": \"world\"}") | ||
close(buff) | ||
wait(readertask) | ||
for result in results | ||
json = JSON.parse(result) | ||
@test json["hello"] == "world" | ||
end | ||
@test length(results) == 2 | ||
end | ||
|
||
function jsonchunk2() | ||
buff = Base.BufferStream() | ||
reader = JSONChunkReader(buff) | ||
results = String[] | ||
readertask = @async begin | ||
for json in reader | ||
push!(results, String(json)) | ||
end | ||
end | ||
|
||
write(buff, "{\"hello\": \"world\"}\n") | ||
write(buff, "{\"hello\": \"world\"}\n") | ||
close(buff) | ||
wait(readertask) | ||
for result in results | ||
json = JSON.parse(result) | ||
@test json["hello"] == "world" | ||
end | ||
@test length(results) == 2 | ||
end | ||
|
||
function jsonchunk3() | ||
buff = Base.BufferStream() | ||
reader = JSONChunkReader(buff) | ||
results = String[] | ||
readertask = @async begin | ||
for json in reader | ||
push!(results, String(json)) | ||
end | ||
end | ||
|
||
write(buff, "\n\n{\"hello\": \"world\"}\n\n") | ||
write(buff, "{\"hello\": \"world\"}\n") | ||
close(buff) | ||
wait(readertask) | ||
for result in results | ||
json = JSON.parse(result) | ||
@test json["hello"] == "world" | ||
end | ||
@test length(results) == 2 | ||
end | ||
|
||
function jsonchunk4() | ||
buff = Base.BufferStream() | ||
reader = JSONChunkReader(buff) | ||
results = String[] | ||
readertask = @async begin | ||
for json in reader | ||
push!(results, String(json)) | ||
end | ||
end | ||
|
||
write(buff, "\n\n{\"hello\": \"world\"}\n\n") | ||
write(buff, "{\"hello\": \"world\"\n") | ||
close(buff) | ||
@test_throws TaskFailedException wait(readertask) | ||
@test length(results) == 1 | ||
end | ||
|
||
function rfc7464chunk1() | ||
buff = Base.BufferStream() | ||
reader = RFC7464ChunkReader(buff) | ||
results = String[] | ||
readertask = @async begin | ||
for chunk in reader | ||
push!(results, String(chunk)) | ||
end | ||
end | ||
|
||
write(buff, OpenAPI.Clients.RFC7464_RECORD_SEPARATOR) | ||
write(buff, "{\"hello\": \"world\"}") | ||
write(buff, OpenAPI.Clients.RFC7464_RECORD_SEPARATOR) | ||
write(buff, "{\"hello\": \"world\"}") | ||
close(buff) | ||
wait(readertask) | ||
for result in results | ||
if !isempty(result) | ||
json = JSON.parse(result) | ||
@test json["hello"] == "world" | ||
end | ||
end | ||
@test length(results) == 3 | ||
end | ||
|
||
function rfc7464chunk2() | ||
buff = Base.BufferStream() | ||
reader = RFC7464ChunkReader(buff) | ||
results = String[] | ||
readertask = @async begin | ||
for chunk in reader | ||
push!(results, String(chunk)) | ||
end | ||
end | ||
|
||
write(buff, "{\"hello\": \"world\"}") | ||
write(buff, OpenAPI.Clients.RFC7464_RECORD_SEPARATOR) | ||
write(buff, "{\"hello\": \"world\"}") | ||
write(buff, OpenAPI.Clients.RFC7464_RECORD_SEPARATOR) | ||
close(buff) | ||
wait(readertask) | ||
for result in results | ||
if !isempty(result) | ||
json = JSON.parse(result) | ||
@test json["hello"] == "world" | ||
end | ||
end | ||
@test length(results) == 2 | ||
end | ||
|
||
function runtests() | ||
linechunk1() | ||
linechunk2() | ||
linechunk3() | ||
jsonchunk1() | ||
jsonchunk2() | ||
jsonchunk3() | ||
jsonchunk4() | ||
rfc7464chunk1() | ||
rfc7464chunk2() | ||
end | ||
|
||
end # module ChunkReaderTests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters