Yxhuvud has quit [Remote host closed the connection]
Yxhuvud has joined #crystal-lang
<FromGitter>
<bajro17> @codenoid it will be something like uber
<FromGitter>
<vladfaust> @newtonapple `def self.new(**options : **T) forall T` would do things. `T` wull be available within a macro within the `def`
lvmbdv has quit [Quit: brb]
DTZUZO has joined #crystal-lang
lvmbdv has joined #crystal-lang
<FromGitter>
<codenoid> or something like GOJEK :D @bajro17
<f1refly>
I established a connection over tcp and got a socket. When i spawn a fiber that puts incoming messages in a channel, shouldn't that socket be blocking when i use .get on it?
<f1refly>
Currently it just receives the first message and then exits my loop. I even set blocking to true explicitly
<oprypin>
hm maybe too strong of a statement. this seems like a line based protocol so may be fine
<oprypin>
i think you're not supposed to use the same socket object for both sending and receiving
<oprypin>
no lol again don't mind me
<oprypin>
this is all fine, i didn't realize that you're communicating with an actual server here
<FromGitter>
<bajro17> hahah yes :)
<FromGitter>
<bew> Do you have control on the server sending the xml?
<FromGitter>
<bajro17> @codenoid you are also from Indonesia?
<FromGitter>
<codenoid> yes, i'm indonesian
<f1refly>
bew: I don't i'm trying to write a library implementing the xmpp standard
<f1refly>
The examples for tcp sockets used the exact same contstruct, but they seem to assume that there's always content that the socket has to offer
<f1refly>
I wandet to avoid periodic checking and was hoping i could use some kind of blocking mechanism instead
<FromGitter>
<bajro17> Ashar?
<oprypin>
f1refly, i would expect this to just work
<f1refly>
I mean i would use `read`, but the xml streams vary heavily in length, so `gets` seemed like the right thing
<f1refly>
I expected that, too
<f1refly>
here is my actual functions, just in case theres something else going wrong https://carc.in/#/r/4wvl
<FromGitter>
<bew> note: instead of doing `(XML.parse message).children.first` you can do `XML.parse(message).children.first`
<FromGitter>
<codenoid> ugh, my internet not stable,
<FromGitter>
<jrfondren> if a .csv has double quotes that aren't part of the data then they can probably have commas in them that you shouldn't split on
<FromGitter>
<jrfondren> well if it's just for practice, you can look for "([^"]+)" in the data and print out any lines you weren't able to handle
<FromGitter>
<codenoid> i think, what inside quote is uri part
<FromGitter>
<jrfondren> oh a slug? that's probably fine then
<FromGitter>
<codenoid> yes, he do scraping
<f1refly>
I fiddled around with the socket some more and it still doesn't work. when i use `socket.gets` and print the output it returns nil. what makes .gets wait when it isn't nil?
<FromGitter>
<jrfondren> try socket.blocking=true
<f1refly>
already did that without any effect whatsoever
<FromGitter>
<jrfondren> the constructor also has a blocking flag
<f1refly>
Also, when i check the socket it says it isn't closed
<f1refly>
Ill try setting it in the constructor
<oprypin>
it's not what you want, it just blocks other fibers
<f1refly>
but it won't run on carc, i guess because the networking is disabled in their sandbox
<FromGitter>
<jrfondren> should you be calling somefunc there?
<f1refly>
ah yes
<f1refly>
with the socket and channel, before the final while loop
<f1refly>
sorry
<FromGitter>
<jrfondren> OK. that works for me, and is clearly blocking
<FromGitter>
<jrfondren> after adding the call and changing it to point to localhost, and running 'nc -l -p 4000'. I can type <a>hi</a> into the server and that code prints it out
<FromGitter>
<jrfondren> so the problem is that only the first message is printed? how are the messages separated?
<f1refly>
I'll just strip down my existing code, seems simpler than rewriting it
<f1refly>
The problem is that the loop exits after the first message
<FromGitter>
<jrfondren> it prints both messages (correcting the </c> to </a>) and then waits for more when it connects to `printf '<a>test1</a>\n<a>test2</c>\n' | nc -C -l -p 4000`
<oprypin>
f1refly, why do you have somefunc if it's never called....
<oprypin>
oh that was addressed
<oprypin>
it still doesnt do anything. ugh
<FromGitter>
<jrfondren> with somefunc() called before the loop, and connecting to some service that emits XML, it reads and prints it out
<f1refly>
Sorry for that, i'm still working on stripping my program down for you
<f1refly>
It works when i use connect to localhost, but doesn't when i use the real server
<FromGitter>
<jrfondren> oh that's a real server?
<FromGitter>
<jrfondren> ok first thing I notice is that 'curl yourdata.forsale:5222' returns a message that doesn't end in CRLF, which your code needs
<f1refly>
yourdata.forsale is running an xmpp server on 5222, the stream is not expected to end according to the specifications
<f1refly>
It's just a very long tcp session where xml is exchanged from time to time. Noone specified any formatting whatsoever, so server implementations vary.
<f1refly>
Most servers filter out any formatting to save resources
<oprypin>
ok but Error connecting to 'localhost:5000': Connection refused
<f1refly>
try running `nc -l -p 5000` like jrfondren said
<f1refly>
then you can send xml to it
<f1refly>
the application expects a server running on 5000 for it to connect
<FromGitter>
<jrfondren> hmm I bet the problem is the expectation that socket.gets always returns complete XML
<f1refly>
But that isn't the issue, since it works marvellous with the local server
<oprypin>
ok i did, it works
<FromGitter>
<jrfondren> you could save and extend the message until it parses as valid XML
<FromGitter>
<jrfondren> so that if, for networking reasons, you receive "<a>test" you can go on to receive "1</a>" and handle that
<oprypin>
`gets` checks for newline specifically
<f1refly>
But that shouldn't be an issue either. The xml fragmets (stanzas) that are sends are complete documents by themselfes and perfectly parsable
<oprypin>
are they separated by newline?
<FromGitter>
<jrfondren> that's a problem too, then
DTZUZO has quit [Ping timeout: 240 seconds]
<oprypin>
and do they never contain a newline?
<f1refly>
oprypin: They seem to be because gets successfully returns the answer to my first query
<f1refly>
jrfondren: Why is that a problem? the socket shouldn't care what it puts through, i could work with broken xml
<FromGitter>
<jrfondren> curl yourdata:5222 returns a message that doesn't end in CRLF (or LF), so I assume that's not to be expected
<FromGitter>
<jrfondren> yourdata.forsale rather
<f1refly>
Also the issue isn't that it can't seperate the messages, the issue is that it exits after the first one. gets returns nil and doesn't block for some reason, which cancels the loop
<oprypin>
so why doesnt it happen locally?
<f1refly>
i have no idea...
<oprypin>
so maybe your expectations for that server are incorrecct
<FromGitter>
<jrfondren> if your XML contains newlines, socket.gets will return before you get valid XML
<f1refly>
jrfondren: the server doesn't return anything when you don't ask it the right thing
<oprypin>
or maybe not "your"
<FromGitter>
<jrfondren> it returns an XML message that says "syntax error". that's not nothing :)
<oprypin>
`gets` returns nil when the stream is closed
<f1refly>
It's the spec thats bailing on me, since the server conforms to the spec
<oprypin>
well sure,... then get a better understanding of the spec
<oprypin>
we dont know the spec so we can only guess, thats not helpful
<f1refly>
jrfondren: oh well, that's more than the server i had installed locally did. must be the configuration
<FromGitter>
<jrfondren> hmm well, try stracing your client to see exactly what it's getting. look for recvfrom syscalls
<FromGitter>
<nulty> Hi guys, is there a way to assert STDOUT in crystal specs? I've looked into mocking but the library I found is more than a year ago and doesn't seem to work with 0.25.1
<f1refly>
oprypin: id save everything i can get from the socket and sort it out later, but that'd still be ugly without blocking
<oprypin>
what do you mean without blocking
<oprypin>
dont you see that it is blocking?
<oprypin>
it blocks until the stream is closed or a line is received. nil means stream is closed
<oprypin>
i assume that consequenct receives on the same socket also return nil
<f1refly>
nulty: there is a way, but in my experience it's better to give the logger class a different io to write to
<f1refly>
oprypin: hm, i haven't considered this. the stream shouldn't be closed but wait for my answer, so i didn't think about it closing
<f1refly>
yes, every read returns nil
<f1refly>
if i where to try and send more stuff into the socket and it doesn't throw an error that means it's still alive, right?
<FromGitter>
<nulty> What do you mean f1frefly? How does the Logger class come into this?
<FromGitter>
<nulty> Oh wait, I'm reading logger.cr now
<f1refly>
you can define a custom io for testing with crystal spec, that's generally better than trying to redirect the normal io :)
DTZUZO has joined #crystal-lang
FromGitter has quit [Remote host closed the connection]
FromGitter has joined #crystal-lang
<FromGitter>
<nulty> In the Formatter? Thats the only place in spec/ I can see the opportunity of setting a custom io
<oprypin>
nulty, change your code to be able to write to something other than stdout
<oprypin>
you're stuck thinking about ways how to change global behavior. the suggestion wasn't about changing it in a different way but about avoiding it
<f1refly>
advice for your whole life :)
<oprypin>
f1refly, i'm pretty sure that's the difference -- it's not that it's running locally, it's that the local server doesn't close the stream but the remote one does
<oprypin>
i think it is indeed possible to close only one half of a socket, though it's strange to do it
<f1refly>
But why would it? It should wait for more input...
<oprypin>
maybe the message you sent doesnt indicate that you will send more afterwards
<oprypin>
it's all about the spec
<f1refly>
It totally does. It's the beginning of capability negotiations
<FromGitter>
<nulty> You mean passing an io in my SUT? `MyThing.new(@io : IO = STDOUT)`
<oprypin>
yea that's great
<FromGitter>
<nulty> And read back whats in the custom IO buffer to assert the behaviour?
<FromGitter>
<Blacksmoke16> check where you are using it, the union of the two types would indicate that in one use of it you are passing it a symbol, while in another ECDSA::Group
<FromGitter>
<iSarCasm> My array literally has only one element of symbol
<FromGitter>
<iSarCasm> I tried tuple but same
<FromGitter>
<Blacksmoke16> could try just typing it as Symbol, like `.as(Symbol)`
<FromGitter>
<Blacksmoke16> otherwise, can you reproduce it easily on carc.in or something?
DTZUZO has joined #crystal-lang
<FromGitter>
<iSarCasm> is group a keyword?
<oprypin>
iSarCasm, where is the macro coming from?
<oprypin>
this would be interesting to make a repro for
<FromGitter>
<iSarCasm> Yep, reproduced
<FromGitter>
<iSarCasm> The bug is somehow related to the name `group`
<FromGitter>
<iSarCasm> I will try to reduce it and then link
<FromGitter>
<Blacksmoke16> 👍
<oprypin>
iSarCasm, where does this sign_and_verify_spec come from though!
<oprypin>
iSarCasm, i think you dont need to report this, the macro itself is bad
<oprypin>
it creates local variable `group`, the problem is not with the name itself
<FromGitter>
<iSarCasm> @oprypin why is it bad?
<FromGitter>
<iSarCasm> @oprypin macros should now use local variables?