aleph

ztellman 2017-09-18T01:57:55.000034Z

@aengelberg @dm3 as a general rule, if there's an error somewhere in a stream transform or operation, the error will be logged and the stream will be closed

ztellman 2017-09-18T01:58:16.000016Z

which should lead to things being cleaned up

ztellman 2017-09-18T01:58:28.000060Z

if that's not true in some situations, I'd consider that a bug in my implementation

aengelberg 2017-09-18T01:59:15.000095Z

I get that it usually cleans up resources properly, but it does not propagate the fact that something went wrong. A stream closing could either mean success or failure.

ztellman 2017-09-18T01:59:48.000019Z

ah, I see

aengelberg 2017-09-18T02:00:45.000083Z

core.async chans have a similar problem.

ztellman 2017-09-18T02:01:08.000101Z

error propagation is a bit tricky in general, imagine if src is being split across two different sinks, a and b

ztellman 2017-09-18T02:01:22.000080Z

if a fails, should that cause src to yield an error too?

ztellman 2017-09-18T02:01:38.000008Z

or should it just continue to feed into b?

ztellman 2017-09-18T02:02:52.000061Z

more to the point, if you're feeding into a network socket and it closes, is that correct behavior or an error?

ztellman 2017-09-18T02:03:40.000054Z

I don't try to give anything richer than TCP offers, basically

ztellman 2017-09-18T02:04:23.000025Z

in order to talk about something succeeding at the application level, you need to define your success criteria using logic layered atop the transport layer, not in the transport layer

ztellman 2017-09-18T02:05:03.000099Z

in fairness, I absolutely could have put! fail with an error rather than return false if, say, map fails

ztellman 2017-09-18T02:05:37.000014Z

but I suspect that people aren't checking for that, and in practice it would just cause the same error to be logged all the way up the topology

aengelberg 2017-09-18T02:07:07.000090Z

Great points

ztellman 2017-09-18T02:07:25.000070Z

this isn't to say that you couldn't create a richer error model, I'm sure other stream libraries do

ztellman 2017-09-18T02:08:11.000145Z

but being the lowest common denominator across all stream abstractions makes that difficult

aengelberg 2017-09-18T02:09:39.000133Z

My original complaint stemmed from the fact that I wanted to convert InputStream into (seq-of bytes), and byte-streams was (unnecessarily?) using a manifold stream in the conversion path, and that conversion silenced errors such as amazon.s3.SocketTimeoutException that I wanted the consumer of the lazy seq to see.

ztellman 2017-09-18T02:10:04.000047Z

hmm

ztellman 2017-09-18T02:10:23.000064Z

it wasn't even logging the error?

aengelberg 2017-09-18T02:10:27.000032Z

It was logging the error

aengelberg 2017-09-18T02:10:29.000125Z

which is great

ztellman 2017-09-18T02:10:35.000090Z

but it wasn't propagating it upwards

aengelberg 2017-09-18T02:10:37.000110Z

yes

ztellman 2017-09-18T02:10:46.000010Z

that is an unnecessary conversion to a stream, I think

aengelberg 2017-09-18T02:10:50.000040Z

which I need to happen for my job to die and mark itself as failure

ztellman 2017-09-18T02:11:01.000087Z

I just need to define a new edge in the conversion graph

ztellman 2017-09-18T02:12:09.000056Z

but I think the same issue would happen if the connection just closed, right?

aengelberg 2017-09-18T02:12:21.000049Z

it depends on the implementation

ztellman 2017-09-18T02:12:22.000118Z

is the S3 client validating the length of the value?

aengelberg 2017-09-18T02:12:37.000091Z

in this case I was reading from S3, not writing to it

ztellman 2017-09-18T02:12:52.000114Z

right, so what happens if the connection closes halfway through downloading the value

ztellman 2017-09-18T02:12:56.000014Z

is an exception thrown?

aengelberg 2017-09-18T02:12:59.000084Z

but I have a different, separate use case that also suffered from this problem in which I was uploading each chunk as a batch to S3 which could potentially fail

ztellman 2017-09-18T02:13:24.000011Z

because if so, that strikes me as a little weird, you wouldn't expect the InputStream to be doing that for you

aengelberg 2017-09-18T02:13:26.000045Z

good question, I'd have to think back to the last time I saw this error happen in prod

ztellman 2017-09-18T02:14:05.000007Z

and this comes back to my original point of "you get some data, it's up to you to decide if it's the correct, full data"

ztellman 2017-09-18T02:14:27.000018Z

I know you don't control the S3 client api, so I'm not really pointing the finger at you here

ztellman 2017-09-18T02:15:13.000008Z

but with anything over the network, lack of an explicit error is not a guarantee that everything's correct, which is kind of why I haven't worried about this part of Manifold very much

aengelberg 2017-09-18T02:15:28.000076Z

I could easily reproduce this by just manually opening an inputstream, waiting out the timeout, and seeing what happens

ztellman 2017-09-18T02:15:30.000147Z

(which isn't a great defense, tbh, but that's my rationale)

aengelberg 2017-09-18T02:17:40.000105Z

so basically my takeaway here is that I need to figure out what exact error I want to be able to see before I complain about not seeing it

ztellman 2017-09-18T02:18:45.000091Z

possibly, or at least consider that failing to process everything isn't always signaled by an exception

ztellman 2017-09-18T02:19:37.000052Z

so having exception propagation doesn't actually mean all issues are surfaced, and may lead to thinking that things are correct when they aren't

aengelberg 2017-09-18T02:20:29.000097Z

I'm fairly confident that my S3 read sockettimeout issue was somehow surfacing through one of the InputStream methods. But I'll need to confirm since you make an interesting point that it might just close it instead