Skip to content

Conversation

vphantom
Copy link
Contributor

@vphantom vphantom commented Feb 4, 2025

You should probably consider this a draft to clean up before merging, as it comes straight from our new dev and this is pretty much his first bit of serious OCaml. I'm attaching the test files to this message, although those are of limited value since they were from our monorepo. They might inspire you though. 😉

ezcurl_sse_tests.tar.gz

Copy link
Owner

@c-cube c-cube left a comment

Choose a reason for hiding this comment

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

There's a lot in there, I think it can be simplified, but it's promising.

A lot of the code should probably live in a SSE submodule in Ezcurl_core for code organization purposes (clearly isolate all the SSE stuff)

id: string option;
data: string option;
retry: int option;
empties: string list; (* Lines without a ':' *)
Copy link
Owner

Choose a reason for hiding this comment

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

I think we should just ignore these at parsing time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean the empties? While the standard seems to suggest they be comments, they could technically be used to convey application-level information so I was reticent to ignore them outright at this level.

Copy link
Owner

Choose a reason for hiding this comment

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

they're comments, an application using them is wrong :)

| Frame of sse_frame
| End_of_stream

type sse_callback = sse_state -> bool
Copy link
Owner

Choose a reason for hiding this comment

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

A docstring indicating what the boolean means would be useful :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

While I agree, and again I'm letting this go, but sometimes we're prey to Fortune 500 enterprises dictating standards breaches that we're forced to implement. I have already had a case with my very first ANSI X12 integration last year. (A field was clearly specified as being fractional to represent percentages, but sure enough I had to make a custom version of that field type for one trading partner which multiplied it by 100…)

Comment on lines +466 to +467
let sq = String.to_seq s in
match Seq.find_index (fun c -> c = ':') sq with
Copy link
Owner

Choose a reason for hiding this comment

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

there really is no need to bring Seq in here at all :). List.exists will be faster and simpler, or even in this case List.mem ':' s is enough.

edit: even better here, sorry, is String.index! Way faster.

let len = Buffer.length body in
let bf_seq = Buffer.to_seq body in
(* Search for some complete line *)
match Seq.find_index (fun c -> c = '\n') bf_seq with
Copy link
Owner

Choose a reason for hiding this comment

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

same thing, String.index/String.index_from, this kind of stuff.

| Some pivot ->
(* Extract line except ending LF *)
let bf_line = Bytes.create pivot in
Buffer.blit body 0 bf_line 0 pivot;
Copy link
Owner

Choose a reason for hiding this comment

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

this is probably better replaced with Buffer.sub

Comment on lines +502 to +503
Buffer.reset body;
Buffer.add_bytes body bf_after;
Copy link
Owner

Choose a reason for hiding this comment

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

sad we have to do that, but yes, Buffer is kind of limited :(

Applied as suggested and we'll go from here.

Co-authored-by: Simon Cruanes <simon.cruanes.2007@m4x.org>
@c-cube
Copy link
Owner

c-cube commented Feb 8, 2025 via email

@vphantom
Copy link
Contributor Author

I'd prefer following the standard and treating them, indeed, as comments :-)

I thought I saw some use them in the wild, but I just double-checked Anthropic and it doesn't use them. Not sure where I saw them then. I still see it as risky to delete them outright but I won't oppose it since we're focused on Anthropic.

id: string option;
data: string option;
retry: int option;
empties: string list; (* Lines without a ':' *)
Copy link
Owner

Choose a reason for hiding this comment

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

still needs to be removed! :)

(afaik the browser API removes these, so it's unlikely anyone actually relies on it)

opt_iter authmethod ~f:(Curl.set_httpauth self.curl);
opt_iter username ~f:(Curl.set_username self.curl);
opt_iter password ~f:(Curl.set_password self.curl);
Curl.set_nosignal self.curl (_get_no_signal ());
Copy link
Owner

Choose a reason for hiding this comment

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

why is this removed?

let sse_frame_with_id sse_f v =
{
event = !sse_f.event;
Copy link
Owner

Choose a reason for hiding this comment

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

do the same as sse_frame_with_event, and same for the functions below (use with to simplify code)

@vphantom
Copy link
Contributor Author

vphantom commented Feb 21, 2025

I haven't touched this PR yet, so if things got added or removed something else is modifying things. (In fact I've been sick all this week, so I definitely didn't touch this.)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants