jemc changed the topic of #ponylang to: Welcome! Please check out our Code of Conduct => https://github.com/ponylang/ponyc/blob/master/CODE_OF_CONDUCT.md | Public IRC logs are available => http://irclog.whitequark.org/ponylang | Please consider participating in our mailing lists => https://pony.groups.io/g/pony
Matthias247 has quit [Read error: Connection reset by peer]
staticassert has quit [Quit: Page closed]
kempe has quit [Ping timeout: 246 seconds]
jemc has quit [Ping timeout: 264 seconds]
kempe has joined #ponylang
chemist69 has quit [Disconnected by services]
chemist69_ has joined #ponylang
amclain has quit [Quit: Leaving]
gmcabrita has quit [Quit: Connection closed for inactivity]
jemc has joined #ponylang
chemist69_ has quit [Ping timeout: 246 seconds]
chemist69 has joined #ponylang
jemc has quit [Ping timeout: 258 seconds]
jemc has joined #ponylang
jemc has quit [Ping timeout: 260 seconds]
virtual_lark has joined #ponylang
gmcabrita has joined #ponylang
virtual_lark has quit [Remote host closed the connection]
staticassert has joined #ponylang
abbiya has quit [Remote host closed the connection]
chemist69 has quit [Ping timeout: 260 seconds]
Xyliton has joined #ponylang
<Xyliton> For some reason my `sent` callback in a `TCPConnectionNotify` is called a lot of times, even though I only write once to the connection itself https://github.com/TheFreakLord/pony-ws/blob/master/websocket_handler.pony#L66
chemist69 has joined #ponylang
<Xyliton> Am I doing anything wrong, or is the tcp connection broken?
<lisael> sent is called back when something is sent by the connection...
<lisael> basically it's an infinite loop
<lisael> Xyliton:
<Xyliton> but isn't `sent` only for `writev` calls?
<Xyliton> *`write`
<Xyliton> and `sentv` for `writev`?
<Xyliton> I have to transform it from a `write` to a `writev` though
<lisael> mmmh looks correct (didn't see the v in the writev call)
<Xyliton> hm...
<Xyliton> no idea?
jemc has joined #ponylang
<lisael> Xyliton: no idea. But it's strange to call writev() in sent()
<lisael> I read the net package code, I don't know why it loops
<lisael> (BTW
<lisael> use "debug"
<lisael> Debug(".")
<Xyliton> How else should I do that? I don't want users to build their own frames all the time, it's just unnecessary complexity
<lisael> prevents from passing the env all around just to debug :) )
<Xyliton> oh, nice
<jemc> Xyliton: have you tried calling `write_final` in your `sent` method?
<Xyliton> but isn't write_final only for a "normal" write?
<Xyliton> I need a writev
<jemc> (we probably need to add a `writev_final` at some point, but for now you can ignore that and call `write_final` multiple times)
<Xyliton> unless there's a way to convert the stuff a Writer returns into a string
<SeanTAllen> im unclear on the connection between Writer and your sent Xyliton
<jemc> Xyliton: it's functionally the same to call `write_final` in a loop - (and that's actually what `writev` used to do internally) - it's just that performance is a little better if you can use the `writev` syscall
<SeanTAllen> its quite a bit better in our testing
<Xyliton> SeanTAllen: my Frame class is using a Writer to construct the frame, which I want to wrap the data a user `write`'s to
<SeanTAllen> ok
<SeanTAllen> Writer.done()
<SeanTAllen> returns an Array[ByteSeq]
<Xyliton> yes
<Xyliton> I'm sending that with a writev in my `sent` right now
<SeanTAllen> which you would pass to writev
<Xyliton> that loops
<SeanTAllen> that is where you are losing me
<SeanTAllen> what are you doing with that array that you are getting from Writer.done ?
<jemc> `for byteseq in writer.done() do write_final(byteseq) end`
<Xyliton> that's what I moved to right now
<Xyliton> instead of calling `writev`
<jemc> then, in the near future, when we add `writev_final`, you can use that for better perf
<Xyliton> because having `writev` inside of my `sent` (in a TCPConnectionNotify) apparently loops
<SeanTAllen> its not clear to me why you would want to do that Xyliton
<SeanTAllen> there's something i'm missing. sorry.
<Xyliton> SeanTAllen: I want to transform from a simple `write` the user does to a full frame
<Xyliton> and a frame is built with a Writer
<Xyliton> so I intercept the message the user sends, transform it, and resend it, swallowing the original message
<SeanTAllen> im not following how that happens
<SeanTAllen> i see you calling writev for every time you enter sent
<SeanTAllen> Frame.build is the result of Writer.done ?
<Xyliton> yes
<SeanTAllen> so
<SeanTAllen> im not sure why in this case you are using writev to start with.
<SeanTAllen> i think you will have an easier time figuring out what is going on
<SeanTAllen> if you loop over the results of your frame and call _write_final for each
<SeanTAllen> the performance isnt as good
<SeanTAllen> but your basic logic will be there
<Xyliton> I got that now
<SeanTAllen> which is i believe what jemc was suggesting
<SeanTAllen> is sent still being called more than once?
<Xyliton> but I don't understand why writev triggers write
<SeanTAllen> what writev?
<Xyliton> the one in sent
<SeanTAllen> i thought you said you removed that
<Xyliton> *triggers sent
<Xyliton> I did
<Xyliton> now it doesn't lock anymore, but it closes the connection
<SeanTAllen> sounds like you have a bug somewhere that you were attributing to writev calling sent which, it doesnt do
<SeanTAllen> and now you are seeing a different symptom of htat bug
<Xyliton> probably because the server I'm sending the data to isn't receiving it the way it should be
<SeanTAllen> _notify.sent is only called from 1 place in TCPConnection and that is in `write`
<Xyliton> is writev calling write?
<Xyliton> also, why is Debug not writing anything to my terminal?
<lisael> Xyliton: compile with -d :)
<Xyliton> ohh
<lisael> (sorry I wasn't clear)
<SeanTAllen> writev is not calling write
<SeanTAllen> you can open up the source to TCPConnection and verify that
<SeanTAllen> btw Xyliton is signature for websocketnotify: fun ref received(conn: TCPConnection ref, data: String)
<SeanTAllen> you are going to end up wanting to change that to match what TCPConnection has
<SeanTAllen> you are going to want data to be an iso
<SeanTAllen> otherwise to hand it off to any other actor, the user will have to copy the data
<Xyliton> oh, true
<SeanTAllen> that's why TCPConnectionNotify supplies an iso
<Xyliton> copying data is "heavy", iirc?
<SeanTAllen> yes
<SeanTAllen> and there's no need for a copy
<SeanTAllen> look at how ` var _read_buf: Array[U8] iso` is used in TCPConnection
<SeanTAllen> i found your problem Xyliton
<SeanTAllen> you are using an SSLConnection
<SeanTAllen> look in SSLConnection
<SeanTAllen> ```
<SeanTAllen> thats were sent is getting called again
<Xyliton> so I can either use writev without SSL, or a loop with SSL?
<SeanTAllen> im fairly certain of that
<SeanTAllen> you can test to verify
<Xyliton> btw, any idea why this is happening? http://hnng.moe/f/OtY
<Xyliton> it appears as if it is reading more data than it should, but the string is the same size
<SeanTAllen> im not sure what i am looking at there
<Xyliton> It's me running a test program twice.
<Xyliton> the payload type is not really necessary to understand this
<Xyliton> the payload size is the size the frame header I received has in it's "payload size" field
<Xyliton> and "actual size" is the size of the string it read
<Xyliton> after that is the string it read, printed to the terminal
<SeanTAllen> ok
<Xyliton> the next two lines ("Sent identification" and "true") can be ignored too
<SeanTAllen> im not sure what the problem is
<Xyliton> there's more data than expected in the first one, but the size it claims to have is the same
<SeanTAllen> how is it claiming to have the same size?
<SeanTAllen> i dont know where any of the values you are printing come from
<SeanTAllen> so its very hard to diagnose
<Xyliton> actual size is the size of the string I read
<Xyliton> payload size is the size I read from the frame header
<SeanTAllen> jemc: i think we need to get rid of sent/sentv write/writev and find a better way to handle than what we have
<Xyliton> the string itself is read from the "Reader", using `block` with the payload size I received
<SeanTAllen> is that string actually 98 characters?
<Xyliton> I'm not sure
<SeanTAllen> how many characters is the output?
<SeanTAllen> im not going to try counting characters in an image
<SeanTAllen> you should be able to select them and know how many characters it is
<Xyliton> the first one is 224
<Xyliton> the second one 98
<SeanTAllen> where is the code that prints these values out?
<Xyliton> interestingly
<Xyliton> once I moved from env.out.print to Debug, it doesn't print that extra data anymore
<SeanTAllen> so im not looking at the code that had the problem?
<Xyliton> I just commented the line out
<SeanTAllen> what supplies the String to that?
<Xyliton> is it possible to set _writeable of a tcpconnection?
<Xyliton> nevermind
<Xyliton> I hackily fixed it
Xyliton has quit [Quit: Leaving.]
amclain has joined #ponylang
dougmacdoug has joined #ponylang
chemist69 has quit [Ping timeout: 246 seconds]
chemist69 has joined #ponylang
iceager has joined #ponylang
iceager has quit [Client Quit]
iceager has joined #ponylang
Matthias247 has joined #ponylang
iceager has quit [Quit: Mutter: www.mutterirc.com]
iceager has joined #ponylang
iceager has quit [Client Quit]
<staticassert> :( pony sync meeting conflicts with my company retrospective
<staticassert> I can call in to the second half i think
Xyliton has joined #ponylang
<Xyliton> Is there any easier method to aquire data from a JSON doc than this?
<Xyliton> `(((data'.data as JsonObject).data("op") as I64).string())`
<Xyliton> data' is the main JsonDoc
<jemc> Xyliton: yes, more or less, that's the best that can be done with the current stdlib json API
<jemc> I think it's generally agreed upon that the stdlib json package has some usability issues
<jemc> more fundamentally, it would likely be more useful in general to have a more static JSON API
<jemc> for example, one where you define a schema for how you expect the JSON input to look like, and the JSON parser spits out statically typed objects instead of a bunch of union types that need to be "unwrapped"
<jemc> another option is the "cooperative-style" parsing I've seen in some lower level languages like C when parsing JSON or messagepack - give an API to say "I expect to see an I64 next, give it to me, or give an error if the input doesn't match what I expect"
<jemc> the schema-based object API could potentially be a code generated wrapper for that cooperative style API
<jemc> it's something I've been wanting to work on a library for, but haven't had the time to do so yet
<Xyliton> oh
<Xyliton> well, I guess "unwrapping" isn't "too" bad for now
<Xyliton> is it possible to load code at runtime and execute it, btw?
<Xyliton> it doesn't have to be in the current "context". I just would like to have a way to dynamically execute code
<jemc> no, not yet - it's on the roadmap, and some preliminary heroic steps in that direction hae already been taken by Praetonus (getting the compiler hooked up to the LLVM JIT), but we're not there yet, and there are still a lot more hurdles to clear
<Xyliton> I'm really looking forward to it! I'm currently trying to implement a discord bot in Pony and it would be really cool to be able to execute code while chatting with your friends
<jemc> so, more or less, a chat-oriented REPL?
<Xyliton> kinda
<Xyliton> I guess I could make that work by spawning a compiler every time
<Xyliton> and grabbing the stdout of the compile dprogram
<Xyliton> *compiled
<Xyliton> my current discord selfbot (based on JS right now) has an eval command which has this kind of output: http://www.hnng.moe/f/OuO
<Xyliton> would be awesome to have that, but with pony
Praetonus has joined #ponylang
<Xyliton> how do I give an object literal a reference to the object creating the literal?
<jemc> Xyliton: something like `object; let creator: CreatorType = this; /* ... */ end`
<Xyliton> that works?
<Xyliton> isn't "this" referring to the object literal then?
<Xyliton> oh, nice
<Xyliton> exactly what I need
<Xyliton> thanks <3
<jemc> even if it were a problem for that reason, you'd still be able to work around it by assigning `this` to a variable outside the object
<jemc> `let that = this; object; let creator: CreatorType = that; /* ... */ end``
_andre has quit [Quit: leaving]
<Xyliton> it tells me that tag isn't a subtype of ref now
staticassert has quit [Ping timeout: 260 seconds]
<jemc> Xyliton: I can't help you figure it out without more context
<Xyliton> jemc: any idea? I don't really now how capabilities work :/
<dougmacdoug> did you try let _parent: TestWSNotify ref = that
<Xyliton> same error
<jemc> Xyliton: what you're doing is pretty much fundamentally unsafe, unfortunately, so it can't be allowed by the compiler
<jemc> your `object` is in a `recover` block because you're trying to recover it to an `iso`
<Xyliton> the code you linked me does that too, though
<Xyliton> it has the object in a recover
<jemc> yep, I wasn't finished typing yet
<Xyliton> oh
<jemc> you can't pass any non-sendable references into a `recover` block
<jemc> so your `TestWSNotify ref` can't be passed in without being deescalated to a `tag` reference
<Xyliton> is there no way for me to get "d" inside of the timer notifyß
<Xyliton> *?
<jemc> let's look at what it is you're trying to do
<Xyliton> when I receive a payload and the value of "op" is 0 I have to set "d" to the value of the payload's "s"
<jemc> the `TestWSNotify` object is held by your `TCPConnectionNotify` object, which in turn is held by the `TCPConnection` actor
<jemc> your timer needs to accept a `TimerNotify` that will be held by the `Timer` inside the `Timers` actor
<Xyliton> yes
<jemc> so they can't both have access to your `TestWSNotify` object as a ref at the same time - doing so would be fundamentally concurrency-unsafe
<jemc> as more than one actor would have mutable access to the same memory space "simultaneously"
<jemc> you probably need to use an intermediate actor to track your test state
<Xyliton> .-.
<jemc> your `TestWSNotify` object, and the `TimerNotify` object could both have access to that intermediate actor
<Xyliton> oh, I see
<jemc> since it would be a `tag` reference, only receiving asynchronous messages
<jemc> I know it can be painful to comply with the ref cap rules sometimes, but it really is saving you a lot of headaches with mutex-hell (or single-threaded purgatory)
<jemc> or at least, that's the fundamental value prop of Pony, so you kind of have to believe in it if you want to stick around :P
<Xyliton> I'm just trying to wrap my head around this whole actor thing
<Xyliton> so I create a new actor (not a class?) and give it to both my TestWSNotify and my TimerNotify?
<Xyliton> should I give it to the TestWSNotify first and have it send it over to the Timer?
<Xyliton> or do I have to create the timer in advance?
<jemc> Xyliton: I'd recommend moving your main logic from `TestWSNotify` into an actor (maybe named `TestWS`), then make a lightweight `object is WebsocketNotify` to pass to the websocket lib
<jemc> just like your lightweight `object is TimerNotify`
<jemc> both anonymous objects would just exist as "glue" to help the websocket lib and timer lib forward calls to your `TestWS` actor
<Xyliton> what should I implement in the "new" WebsocketNotify then? just forwarding the data it get's to the actor?
<jemc> yep, pretty much
dougmacdoug has quit [Quit: dougmacdoug]
<Xyliton> oh, I see
<Xyliton> thanks a lot <3
chemist69 has quit [Ping timeout: 246 seconds]
chemist69 has joined #ponylang
Xyliton has quit [Quit: Leaving.]