00:00:08 | fghj | Araq: works great, thanks again! |
00:00:21 | * | dapz joined #nimrod |
00:01:20 | * | dapz quit (Client Quit) |
00:01:22 | Araq | flaviu: btw please test that the tester still works with the new pegs and add this breaking change to news.txt in bold |
00:05:12 | * | Boscop quit (Read error: Connection reset by peer) |
00:05:41 | * | Boscop joined #nimrod |
00:05:52 | * | dapz joined #nimrod |
00:05:58 | fowl | flaviu, you should do it as a template so you can avoid some copying |
00:06:49 | Araq | fowl: I think it can only be done as a macro |
00:07:12 | fowl | template box(value):expr = block: var result{.gensym.}: ref type(value); new result; result[] = value; result |
00:07:32 | Araq | you have to destruct Foo(x, y) into Foo and (x, y) |
00:07:41 | * | dapz quit (Client Quit) |
00:08:07 | Araq | can't do that with a template |
00:08:15 | fowl | oh this to call some initialize() or something |
00:08:24 | fowl | i thought he wanted foo(a: 1,b: 2) |
00:08:31 | fowl | new foo(a: 1) |
00:08:47 | Araq | yes but your template does: result[] = value |
00:09:01 | Araq | which is the copy we can avoid with a macro |
00:09:10 | Araq | whether that matters is another thing |
00:09:31 | fowl | hopefully nothing gets copied in "new[] = foo(a: 1)" |
00:09:54 | fowl | oh i see what you're saying |
00:11:02 | * | vendethiel- joined #nimrod |
00:11:37 | * | zahary1 joined #nimrod |
00:12:48 | flaviu | Sorry, I was getting food. |
00:13:48 | * | q66[lap] quit (Ping timeout: 250 seconds) |
00:14:44 | flaviu | Araq: https://gist.github.com/flaviut/1ae1d7deac4c57d0a84c |
00:15:34 | flaviu | IIRC, last time I benchmarked it, the copy is optimized out. |
00:15:49 | flaviu | s/,//g |
00:15:57 | Araq | depends on the type |
00:15:57 | * | vendethiel- quit (Read error: Connection timed out) |
00:16:07 | * | vendethiel- joined #nimrod |
00:16:19 | flaviu | Well, in cases where it isn't optimized, I don't see it as a problem |
00:17:23 | Araq | things are not that simple. some fool will use it in a benchmark and then we need to tell him to not use it |
00:17:48 | Araq | and he will be like "oh, so it's easy to use but hard to write efficient code" |
00:19:20 | flaviu | Easy rebuttal: "Thanks for pointing out this corner case! We made a conscious decision to implement it the way it is in the interest of simple code. Our benchmarks have overlooked this case, it will be fixed in the next release." |
00:20:00 | Araq | well maybe that's acceptable to you, but I'm really tired of having to excuse myself all the time |
00:20:33 | * | willwillson quit (*.net *.split) |
00:20:33 | * | bjz quit (*.net *.split) |
00:20:33 | * | vendethiel quit (*.net *.split) |
00:20:33 | * | [CBR]Unspoken quit (*.net *.split) |
00:20:33 | * | Hodapp quit (*.net *.split) |
00:20:34 | * | JStoker quit (*.net *.split) |
00:20:34 | * | milosn quit (*.net *.split) |
00:20:34 | * | zahary quit (*.net *.split) |
00:20:34 | * | Pisuke quit (*.net *.split) |
00:20:35 | * | heinrich5991 quit (*.net *.split) |
00:20:35 | * | xyproto quit (*.net *.split) |
00:20:52 | fowl | flaviu, you ought to have box send its params to some function like initialize() |
00:21:03 | flaviu | fowl: No actually. |
00:21:06 | flaviu | I have a better idea |
00:21:15 | flaviu | Allow overloading methods on type names |
00:21:34 | fowl | what is a type name |
00:21:47 | flaviu | like overloading Foo() |
00:21:50 | * | dapz joined #nimrod |
00:22:00 | flaviu | where type Foo = object... |
00:22:05 | * | [CBR]Unspoken joined #nimrod |
00:22:13 | fowl | you can already do this with a proc |
00:22:45 | Araq | flaviu: with cs:partials you can have foo and Foo |
00:24:23 | * | willwillson joined #nimrod |
00:25:54 | * | heinrich5991 joined #nimrod |
00:25:54 | * | milosn joined #nimrod |
00:25:54 | * | Pisuke joined #nimrod |
00:25:54 | * | xyproto joined #nimrod |
00:26:15 | * | Pisuke quit (Max SendQ exceeded) |
00:26:42 | * | Hodapp joined #nimrod |
00:26:42 | * | JStoker joined #nimrod |
00:26:45 | flaviu | But I want Foo(a,b,c) |
00:27:00 | flaviu | Mostly cosmetic, but I think it's much better than all the initFoo, newFoo |
00:27:03 | * | JStoker quit (Max SendQ exceeded) |
00:27:17 | * | JStoker joined #nimrod |
00:27:44 | fowl | then make it so that passing params can be enabled by implementing initialize(self:ref Foo, a,b,c) |
00:28:06 | * | Pisuke joined #nimrod |
00:28:24 | fowl | otherwise, there is not enough information available |
00:28:54 | fowl | to initialize'er |
00:33:17 | flaviu | fowl: IMO, that's far too compilcated |
00:34:02 | flaviu | These functions now need to start caring about what the type wants |
00:34:28 | flaviu | I think my method is simpler, just a 1-2 line change in the compiler |
00:34:37 | flaviu | And you can use factories, as well as constructors |
00:35:22 | * | dapz quit (Quit: My MacBook has gone to sleep. ZZZzzz…) |
00:35:51 | * | dapz joined #nimrod |
00:37:53 | Araq | flaviu: last time i checke your 1-2 line change in the compiler was not sufficient |
00:38:00 | Araq | *I checked |
00:38:20 | flaviu | I don't doubt it has a few bugs |
00:38:55 | fowl | nothing new should be added unless it is efficient like a swiss clock |
00:39:17 | fowl | they make the best clocks |
00:39:38 | fowl | better than germany at least |
00:42:27 | Araq | fowl: make that "let's fix the remaining bugs first" |
00:45:36 | flaviu | Ok, fair enough |
00:53:21 | Araq | good night |
00:57:53 | * | shodan45 joined #nimrod |
00:58:11 | * | dapz quit (Quit: My MacBook has gone to sleep. ZZZzzz…) |
00:59:29 | fowl | good night |
01:00:38 | * | mko quit (Quit: Bye.) |
01:01:45 | * | askatasuna joined #nimrod |
01:06:53 | * | dapz joined #nimrod |
01:10:35 | * | kshlm joined #nimrod |
01:10:46 | * | kshlm quit (Client Quit) |
01:23:18 | * | askatasuna quit (Quit: WeeChat 1.0.1) |
01:33:39 | * | dapz quit (Quit: My MacBook has gone to sleep. ZZZzzz…) |
01:35:46 | * | dapz joined #nimrod |
01:39:44 | * | dapz quit (Client Quit) |
01:48:28 | * | saml_ joined #nimrod |
02:04:38 | * | dapz joined #nimrod |
02:15:37 | * | willwillson quit (Read error: Connection reset by peer) |
02:21:22 | * | xenagi joined #nimrod |
02:23:44 | * | Fr4n quit (Quit: Leaving) |
02:30:54 | * | dapz quit (Quit: My MacBook has gone to sleep. ZZZzzz…) |
02:45:04 | * | flaviu quit (Remote host closed the connection) |
03:02:55 | * | darkf_ joined #nimrod |
03:04:10 | * | darkf quit (Ping timeout: 265 seconds) |
03:04:29 | * | kshlm joined #nimrod |
03:14:03 | Varriount | Araq: Regarding the string optimization, where in ccgexpr should I modify? The value assignment code?> |
03:14:12 | * | darkf_ is now known as darkf |
03:21:09 | * | saml_ quit (Read error: Connection reset by peer) |
03:38:04 | * | quasinoxen joined #nimrod |
03:39:57 | Varriount | Araq: Is there some already existing compiler code that copies the contents of one string into another string? |
03:58:03 | * | xenagi quit (Quit: Leaving) |
03:59:02 | * | fowl quit (Quit: Leaving) |
04:05:33 | * | nande quit (Remote host closed the connection) |
04:11:53 | * | darkf_ joined #nimrod |
04:13:14 | * | darkf quit (Disconnected by services) |
04:13:15 | * | darkf_ is now known as darkf |
04:20:54 | * | darkf_ joined #nimrod |
04:22:25 | * | darkf quit (Ping timeout: 272 seconds) |
04:22:29 | * | darkf_ is now known as darkf |
04:26:03 | * | darkf_ joined #nimrod |
04:29:18 | * | darkf quit (Ping timeout: 265 seconds) |
04:33:43 | * | ARCADIVS joined #nimrod |
04:34:27 | * | darkf_ quit (Ping timeout: 272 seconds) |
04:49:52 | * | darkf joined #nimrod |
04:55:20 | * | boydgreenfield joined #nimrod |
05:31:04 | * | johnsoft quit (Ping timeout: 245 seconds) |
05:31:53 | * | johnsoft joined #nimrod |
05:51:37 | * | Varriount_ joined #nimrod |
05:53:45 | * | Varriount quit (Ping timeout: 258 seconds) |
06:03:40 | * | gokr joined #nimrod |
06:05:54 | * | gokr_ quit (Ping timeout: 246 seconds) |
06:09:00 | * | gokr_ joined #nimrod |
06:11:54 | * | gokr quit (Ping timeout: 245 seconds) |
06:29:24 | * | uber quit (Ping timeout: 258 seconds) |
06:31:04 | * | uber joined #nimrod |
06:33:59 | Araq | Varriount_: yes its the assignment generation. There exists code for it, but you want a different logic. I suggest to introduce a new .compilerproc. |
06:37:17 | * | gokr joined #nimrod |
06:41:25 | * | gokr_ quit (Ping timeout: 260 seconds) |
06:42:00 | gokr1 | Morning guys |
06:42:34 | gokr1 | Araq: Sorry if I annoyed you last night, not my intention. |
06:42:58 | Araq | gokr1: nah, I simply enjoy to rant |
06:43:05 | gokr1 | Hehe |
06:45:15 | * | cat joined #nimrod |
06:45:39 | * | cat is now known as Guest59902 |
06:46:14 | * | Guest59902 quit (Client Quit) |
06:59:47 | * | boydgreenfield quit (Quit: boydgreenfield) |
07:22:24 | gokr1 | Tuples have their own internal "Field0", "Field1" names, and using marshal to serialize to JSON will use those names. |
07:29:41 | * | Trustable joined #nimrod |
07:29:49 | Araq | correct. |
07:33:40 | gokr1 | The use of the internal names - how so? Looked up tuple equivalence - and while you write it may change - the names are indeed needed to be the same too. |
07:34:36 | gokr1 | Oh, so... at runtime you unify only based on types and order perhaps? |
07:34:48 | gokr1 | So you don't have the names at runtime? |
07:40:12 | * | kshlm quit (Ping timeout: 272 seconds) |
07:45:07 | Araq | well the names are required to be the same, but this is about to change |
07:46:03 | Araq | plus there always were unnamed tuples: (7, 8) |
07:46:09 | Araq | plus there always were unnamed tuples: (7, 8 ) |
07:46:42 | * | gokr quit (Ping timeout: 246 seconds) |
07:47:26 | Araq | and then you have the nice codegen problem that tuple[a, b: int] is "better" than tuple(int, int) |
07:47:38 | Araq | as it has more information |
07:47:54 | Araq | but sometimes the names are introduced much later |
07:48:08 | Araq | so the codegen has no chance |
07:50:43 | * | gokr1 quit (Ping timeout: 244 seconds) |
08:01:39 | * | zahary1 left #nimrod (#nimrod) |
08:14:29 | * | darkf_ joined #nimrod |
08:15:13 | * | darkf quit (Disconnected by services) |
08:15:15 | * | darkf_ is now known as darkf |
08:22:18 | * | gokr joined #nimrod |
08:31:46 | * | q66[lap] joined #nimrod |
08:40:38 | * | gokr1 joined #nimrod |
08:44:46 | * | Etheco joined #nimrod |
09:12:34 | * | bjz joined #nimrod |
09:14:37 | gokr1 | Am I correct that the new high level socket is net.im, and that sockets.nim is... being transformed into rawsockets.nim? |
09:15:27 | gokr1 | net.nim of course. |
09:24:08 | * | forgottenleaf joined #nimrod |
09:24:14 | * | forgottenleaf left #nimrod ("Textual IRC Client: www.textualapp.com") |
09:33:14 | * | dom96_ joined #nimrod |
09:33:33 | dom96_ | gokr: sockets.nim is deprecated |
09:33:51 | gokr1 | That's what I meant I think :) |
09:34:25 | gokr1 | But it doesn't say so, or perhaps I missed something. |
09:41:56 | dom96_ | Maybe the docs haven't been updated. |
09:42:16 | gokr1 | I was only looking in the source |
09:52:42 | gokr1 | So for select - its selectors.nim to use now? |
10:12:10 | * | Boscop_ joined #nimrod |
10:14:42 | gokr1 | I added a "*" for select in net.nim so I can use it. |
10:14:52 | * | Boscop quit (Ping timeout: 245 seconds) |
10:42:41 | gokr1 | So I whipped up a little spawning echo server - using spawn instead of asynch, and I am hammering it a bit. |
10:43:37 | gokr1 | It just reads one line and echoes it back and closes socket. |
10:52:06 | * | q66[lap] quit (Ping timeout: 250 seconds) |
10:54:56 | dom96_ | gokr1: what are you using select for? |
10:55:10 | dom96_ | Indeed, you should use selectors instead. |
10:55:11 | * | ARCADIVS quit (Quit: ARCADIVS) |
10:55:24 | gokr1 | Yeah, to make sure it uses epoll etc, right? |
10:55:28 | dom96_ | yes |
10:56:40 | gokr1 | Which paste service do you guys use? |
10:57:41 | gokr1 | dom96_: http://pastebin.com/ujhfiN9M |
10:58:20 | Trustable | gokr1: github gist |
10:59:39 | gokr1 | So anyway, it seems to fly pretty darn good. But I will move to Selectors. |
11:03:58 | * | q66[lap] joined #nimrod |
11:07:01 | * | q66[lap]_ joined #nimrod |
11:08:05 | * | [CBR]Unspoken quit (Ping timeout: 244 seconds) |
11:09:33 | dom96_ | gokr1: please compare async await to spawn if you have some time. |
11:09:39 | dom96_ | (speed wise) |
11:10:16 | gokr1 | yeah, this was a bit of why I am doing this. And also, I think... if you use async/await all you do still needs to play by those rules - right? |
11:10:18 | * | q66[lap] quit (Ping timeout: 250 seconds) |
11:10:43 | gokr1 | So a spawning server may be better for our little case here - I mean, when say each request ends up doing MySQL calls etc. |
11:37:41 | * | bjz quit (Quit: Textual IRC Client: www.textualapp.com) |
11:41:40 | gokr1 | dom96_: Its not fully apparent to me how to use selectors :). I will look into it later. |
11:42:14 | * | gokr1 left #nimrod (#nimrod) |
11:43:49 | * | bjz joined #nimrod |
12:03:37 | * | gokr1 joined #nimrod |
12:14:39 | * | xcombelle joined #nimrod |
12:27:14 | * | gokr_ joined #nimrod |
12:27:45 | * | gokr quit (Ping timeout: 246 seconds) |
12:32:55 | * | xyproto left #nimrod ("WeeChat 1.0.1") |
12:43:31 | * | gokr joined #nimrod |
12:43:31 | * | gokr_ quit (Read error: Connection reset by peer) |
12:48:55 | * | jlebrech joined #nimrod |
12:50:15 | jlebrech | I see you can target C and also JS. are there directives to check what target it's being compiled for? |
12:50:52 | * | xcombelle quit (Quit: Quitte) |
12:52:35 | gokr1 | jlebrech: You do "nimrod c myfile.nim" for C, "nimrod cpp" for C++ etc |
12:52:39 | gokr1 | nimrod --help |
12:52:50 | gokr1 | Oh... sorry, misunderstood. |
12:53:09 | gokr1 | Some kind of when you mean. |
12:53:16 | jlebrech | gokr1: ok, that's cool. but how does the code know what it's being compiled for? |
12:54:26 | gokr1 | You can use "when defined(js):" etc for compile time ifs |
12:54:36 | jlebrech | ok cool |
12:55:23 | gokr1 | If you grep for "when defined" you find lots :) |
12:56:04 | jlebrech | i'm thinking of making a proof of concept app which compiles into a server side and client side, and the client side remote calls the server side |
12:56:59 | gokr1 | The ZeroMQ stuff might be useful I guess. |
12:57:35 | jlebrech | client side js, so i'll be doing ajax calls i think |
12:58:10 | jlebrech | i'd like to see a framework like meteor written in nim(rod) |
13:02:14 | gokr1 | Ah |
13:02:24 | gokr1 | Araq: Awake? |
13:05:44 | * | darkf quit (Quit: Leaving) |
13:06:45 | wan | gork1: your pastebin was very short-lived. I was interested :) |
13:06:52 | wan | but couldn't see it |
13:06:56 | gokr1 | Oh, I can paste again |
13:07:44 | * | bjz quit (Ping timeout: 244 seconds) |
13:10:47 | * | BitPuffin joined #nimrod |
13:11:51 | gokr1 | wan: https://gist.github.com/gokr/df5b6de5d87ac535abf9 |
13:12:19 | gokr1 | So... it has lots of comments - I intend to make a little newbie article about it. |
13:12:45 | gokr1 | Important: This is using bigbreak *and* you need to hack net.nim putting in a "*" after select. |
13:12:56 | gokr1 | The old select there is not public anymore, not sure why. |
13:13:17 | gokr1 | If you throw ab on it I think the numbers are quite nice. |
13:14:11 | gokr1 | And that little "spawn" word in there has a lot of punch behind it - I think Araq (who wrote that?) has made the thread pool quite intelligent checking number of cores etc - trying to adapt. |
13:14:49 | woodgiraffe | Is there a short-hand for turning a sequence into an array? |
13:37:56 | * | bjz joined #nimrod |
13:50:41 | Araq | woodgiraffe: that's not possible in general |
13:50:55 | Araq | an array's length has to be compile-time value |
14:17:43 | * | [CBR]Unspoken joined #nimrod |
14:24:45 | woodgiraffe | I see, thanks for the response |
14:26:55 | * | [CBR]Unspoken quit (Quit: Leaving.) |
14:27:17 | * | [CBR]Unspoken joined #nimrod |
14:46:48 | wan | gokr1: I like the comments explaining in detail what happens |
14:47:08 | wan | However, it doesn't seem to respond well to wrk |
15:06:55 | * | bjz quit (Read error: Connection reset by peer) |
15:07:21 | * | bjz joined #nimrod |
15:37:33 | * | xcombelle joined #nimrod |
15:53:29 | gokr1 | wan: I need to read the code closer and really be sure that those comments are correct. One thing I would like someone to explain in detail to me (or point me to) is exactly how "new" works :) |
15:53:40 | gokr1 | wan: It didn't respond well? |
15:56:16 | wan | wrk doesn't receive valid responses |
16:00:15 | * | Matthias247 joined #nimrod |
16:10:21 | gokr | oh, its not making proper http at all, that is probably why. |
16:10:29 | gokr | it just echoes |
16:15:01 | * | itsmeront joined #nimrod |
16:22:56 | * | itsmeront quit (Quit: Page closed) |
16:23:25 | * | itsmeront joined #nimrod |
16:24:08 | * | superfunc__ joined #nimrod |
16:36:22 | * | mko joined #nimrod |
16:37:21 | * | johnsoft quit (Ping timeout: 260 seconds) |
16:37:28 | * | johnsoft joined #nimrod |
16:53:36 | * | will joined #nimrod |
17:06:53 | * | jlebrech quit (Remote host closed the connection) |
17:18:09 | * | gokr_ joined #nimrod |
17:21:24 | * | gokr quit (Ping timeout: 246 seconds) |
17:26:30 | * | untitaker quit (Ping timeout: 265 seconds) |
17:32:37 | * | itsmeront quit (Ping timeout: 246 seconds) |
17:33:03 | * | untitaker joined #nimrod |
17:35:25 | * | superfunc__ quit (Ping timeout: 246 seconds) |
17:36:48 | * | xcombelle quit (Ping timeout: 246 seconds) |
17:41:24 | * | Fr4n joined #nimrod |
18:02:15 | * | BitPuffin quit (Ping timeout: 244 seconds) |
18:15:31 | wan | gokr: Oh yeah, that was it. I could make it work when sending "HTTP/1.1 200 OK\LContent-Length: "[...] |
18:16:26 | wan | performance isn't much, though. I got less than asynchttpserver... |
18:18:19 | * | superfunc__ joined #nimrod |
18:18:27 | * | superfunc__ left #nimrod (#nimrod) |
18:18:51 | * | superfunc__ joined #nimrod |
18:18:53 | * | xcombelle joined #nimrod |
18:19:49 | * | quasinoxen quit (Ping timeout: 245 seconds) |
18:23:54 | * | quasinoxen joined #nimrod |
18:40:26 | * | dloss joined #nimrod |
18:43:22 | * | silven joined #nimrod |
18:46:25 | * | dloss quit (Remote host closed the connection) |
18:51:35 | woodgiraffe | Any pointers what the magic pragma does? |
18:58:31 | * | vegai joined #nimrod |
18:58:49 | * | vegai left #nimrod (#nimrod) |
19:02:23 | * | Ven joined #nimrod |
19:14:45 | * | BlaXpirit joined #nimrod |
19:15:23 | Varriount_ | woodgiraffe: It's an intrinsic procedure provided by the Nimrod compiler. |
19:15:49 | gokr_ | I would presune magic is equivalent to a so called primitive in Smalltalk |
19:16:01 | gokr_ | exactly |
19:16:12 | dom96_ | gokr_: need help with selectors? |
19:16:14 | * | Varriount_ is now known as Varriount |
19:17:17 | gokr_ | wan: It should probably be less but it could handle more work on a multicore box. |
19:17:38 | gokr_ | and not require everything to be asynch |
19:18:34 | gokr_ | but I felt performance was fairly good? Did you use -d:release :) |
19:24:40 | wan | Yes, I did. I only got 13_500 when asynchttpserver gets 15_000, mongrel2+nawak gets 24_000, go gets 50_000, lwan and monkey/duda get 70_000+ |
19:25:11 | wan | in rps, requests/second |
19:27:16 | * | mko quit (Ping timeout: 265 seconds) |
19:32:37 | Araq | wan: that's pretty bad. any idea why we're so slow? |
19:33:28 | dom96_ | wan: limit go to 1 thread and see how it performs. |
19:34:57 | * | mko joined #nimrod |
19:38:26 | * | Ven quit (Quit: My MacBook has gone to sleep. ZZZzzz…) |
19:40:49 | gokr_ | it diesnt do keepalive |
19:41:30 | gokr_ | so perhaps that is it |
19:43:08 | gokr_ | and oh, I never fixed it to use selectors.nim |
19:55:56 | * | Ven joined #nimrod |
19:58:56 | * | gokr joined #nimrod |
19:58:56 | * | gokr_ quit (Read error: Connection reset by peer) |
20:03:49 | * | superfunc__ quit (Ping timeout: 246 seconds) |
20:03:55 | * | dloss joined #nimrod |
20:05:45 | wan | dom96: oh that's true , asynchttpserver and gokr's example probably aren't using multi-thread, so there's that |
20:06:51 | wan | however it does count, if we don't have a solution for multithread+async yet |
20:07:05 | * | dloss quit (Remote host closed the connection) |
20:08:18 | wan | (I'm on a old quad-core laptop i5 M520, if you want to know) |
20:09:30 | * | q66[lap]_ quit (Changing host) |
20:09:30 | * | q66[lap]_ joined #nimrod |
20:09:38 | * | q66[lap]_ is now known as q66[lap] |
20:11:39 | * | Fr4n quit (Ping timeout: 258 seconds) |
20:15:11 | wan | Can we even have a (distributor thread + worker threads) architecture with async, with the per-thread GC heap? |
20:18:53 | gokr1 | wan: My example uses threads. But not the asynchttpserver AFAIK. |
20:19:17 | Araq | no idea why people here think async+threads is an unsolved problem for Nim |
20:19:24 | * | flaviu joined #nimrod |
20:19:29 | Araq | it's trivial to combine them |
20:19:43 | gokr1 | Now, one thing - my code was just meant as a minimal socket server - not HTTP. |
20:19:50 | gokr1 | So it doesn't do keepalive. |
20:19:56 | Araq | the only thing it doesn't support is some totally unrealistic use cases |
20:19:56 | gokr1 | That is a very big diff. |
20:21:04 | gokr1 | My example was mainly me learning - so I stayed away from async for the moment. |
20:21:20 | gokr1 | And for my use cases I would want to leverage the threadpool. |
20:21:43 | gokr1 | One issue we have today is that we don't utilize all the cores on the servers we have. |
20:22:57 | flaviu | gokr1: Relevant to the current discussion, but I added a paragraph explaining the question to https://github.com/Araq/Nimrod/wiki/Common-Criticisms |
20:23:15 | flaviu | er, irrelevent |
20:25:03 | gokr1 | flaviu: But... just to make sure I am not missing something - I can't call the same proc foo with either "T" or "ref T" - can I? |
20:25:37 | flaviu | Yes, you can. `ref T` is declared with let, `T` is declared with var |
20:25:55 | flaviu | both are effectively `T*` |
20:26:21 | flaviu | I may have misplaced the asterisk, but you get the idea. |
20:26:31 | gokr1 | hum, hum. So... is that always the case? That a "ref T" can be used instead of a "T" and vice versa? |
20:26:42 | gokr1 | I mean, as an arg. |
20:26:49 | flaviu | Yep. |
20:27:03 | flaviu | but not always vice versa |
20:27:16 | flaviu | only of the T is declared as a var |
20:27:20 | flaviu | *if |
20:27:50 | flaviu | Actually, I'm not sure if you can give a var T to a ref T |
20:28:20 | flaviu | No, that would be unsafe. I'm sure you can't |
20:28:48 | gokr1 | So a "var T" can take either a "T" or a "ref T". |
20:29:17 | gokr1 | I gotta ... check the manual again, is this described in there? |
20:29:18 | flaviu | As long as that `T` is declared as a var |
20:29:58 | flaviu | You can't pass a `let a: T` to a var T, that would allow modification and break the purpose of `let` |
20:30:55 | Araq | flaviu: your example is still wrong |
20:31:09 | Araq | you cannot pass 'var b: T' to foo taking a 'ref T' |
20:31:23 | flaviu | Araq: Oh, sorry |
20:31:31 | flaviu | That's a typo |
20:31:35 | flaviu | My fault |
20:32:05 | flaviu | sorry about the confusion gokr, that was supposed to be var |
20:33:23 | gokr1 | Ok, rewind. So ... I can not mix these guys, right? One is a ref - the other is a T, right? |
20:33:38 | gokr1 | Or else my head starts spinning. |
20:33:53 | Araq | and since we don't have auto-deref, you cannot pass 'ref T' to something taking a 'var T' |
20:34:01 | gokr1 | Good. |
20:34:10 | flaviu | Araq: Really? I was sure I've done that |
20:34:14 | gokr1 | I don't like magic in these cases. |
20:34:35 | Araq | flaviu: you can doo x.field instead of x[].field but that's about it |
20:34:49 | gokr1 | Ah, right. |
20:35:19 | Araq | auto-deref in more contexts has been delayed until after 1.0 is out |
20:35:23 | gokr1 | So this means - your example of foo - would need to different foo, right? |
20:35:26 | gokr1 | two. |
20:36:29 | * | Fr4n joined #nimrod |
20:36:33 | gokr1 | Btw, I think one thing could use some more explanation - or perhaps I missed it in the language def. And that is the proc "new". |
20:37:31 | gokr1 | As can be seen in my n00b code: https://gist.github.com/gokr/df5b6de5d87ac535abf9 |
20:37:43 | * | xcombelle quit (Ping timeout: 258 seconds) |
20:37:49 | gokr1 | I do "var client: Socket = Socket()" in the middle there. |
20:38:26 | gokr1 | And I think this is equivalent to "var client: Socket" followed by "new(client)" |
20:38:42 | Araq | yes, exactly |
20:39:03 | flaviu | Araq: ^ exactly the situation where I'd like a `box` function |
20:39:16 | gokr1 | So... "new(client)" checks the type of client, and initializes the memory there, right? And its in the stack frame? |
20:39:24 | Araq | flaviu: I know |
20:39:45 | flaviu | No, new(client) places it on the heap |
20:40:06 | flaviu | (hopefully I'm not wrong about that too) :P |
20:40:20 | gokr1 | Okidoki. So new allocates on the heap - always? |
20:40:28 | gokr1 | And "Socket()" does too? |
20:40:30 | flaviu | Just like malloc |
20:40:42 | flaviu | Depends if Socket is a ref T, or just a T |
20:40:45 | Araq | conceptually, yes. one we got escape analysis things will be harder to tell ;-) |
20:41:06 | * | Mat3 joined #nimrod |
20:41:11 | Araq | *once |
20:41:15 | Mat3 | hi all |
20:41:33 | flaviu | Oh, socket is a ref object |
20:41:44 | gokr1 | yes |
20:41:44 | flaviu | So Socket() will place it on the heap |
20:42:02 | gokr1 | And... that is because it is a ref object? |
20:42:17 | Araq | yeah, not sure that was our best idea for efficiency. |
20:42:34 | flaviu | Aren't sockets supposed to be reused? |
20:43:10 | Araq | kind of, yeah |
20:43:13 | flaviu | nm, forgot about reference counting |
20:44:14 | flaviu | btw, has ref T never been passable to var T? I was sure I'd used that |
20:45:10 | Araq | it was never possible |
20:46:49 | * | dom96_ quit (Ping timeout: 272 seconds) |
20:48:05 | wan | Araq: "it's trivial to combine them" Good, that's what I wanted to know. I wasn't sure if it even was possible. The false impression probably comes from the fact that we have to share/send something between the threads (maybe just a socket / an int?), and if stuff is on different heaps... |
20:48:10 | gokr1 | So if Socket was NOT a ref object - and I write "var client: Socket = Socket()" - it doesn't use new and thus it ends up in the frame, right? |
20:48:37 | flaviu | Araq: What did you mean by test the tester? I'm running koch test, is that what you mean? |
20:48:51 | Araq | flaviu: yes |
20:48:57 | Araq | gokr1: yes |
20:50:39 | Araq | wan: well exactly. the limitation is that the dispatcher can only run in one thread and if you 'spawn' you cannot really access the dispatcher from the spawn'ed proc, but it's nothing a message queue cannot solve |
20:51:03 | Mat3 | short byquestion: how can I initialize an char array of fixed width (say 30 elements) ? |
20:51:12 | gokr1 | Okidoki - so my code allocates it on the heap, but then we do "spawn handle(client)" so... that means we hand over the ref to another thread. That can't be good. |
20:51:15 | Mat3 | I mean by declaration |
20:51:37 | flaviu | Mat3: array[30, T]? |
20:51:57 | Araq | Mat3: variables are always intialized to 0, but you can also use an array constructor: [0, 1, 2, 3] |
20:52:05 | Mat3 | thanks |
20:52:12 | Araq | for 30 elements it's tedious but nothing a macro cannot solve |
20:52:55 | Araq | gokr1: well it copies the socket over, so it's safe, but not really efficient |
20:53:33 | Araq | spawn changes parameter passing semantics. a 'ref' is deeply copied |
20:53:45 | Araq | (that's all documented btw) |
20:54:08 | gokr1 | Yes, I read that actually! |
20:54:31 | gokr1 | But this means... I really don't need to heap allocate it in the first place, right? |
20:54:39 | gokr1 | Since it will be copied over. |
20:55:02 | Araq | yeah but you have no choice. Socket is a ref |
20:55:11 | gokr1 | True. |
20:55:22 | flaviu | Araq: Does that use malloc? |
20:55:33 | Araq | rawsockets should provide a better interface |
20:55:37 | flaviu | If so, I'm sure that Socket()[] will be optimized out. |
20:55:45 | Araq | but I don't know how usuable that is yet |
20:55:49 | gokr1 | Btw, "select" in net.nim is not public. |
20:55:58 | gokr1 | I presume its because we don't want people to use it anymore or? |
20:56:11 | gokr1 | I threw in a "*" to use it. |
20:56:17 | gokr1 | Now I need to grok selectors.nim |
20:56:33 | Araq | well you're supposed to use selectors.nim |
20:56:39 | Araq | or rather the dispatcher |
20:56:47 | Araq | flaviu: we don't use malloc |
20:56:57 | Araq | we have our own allocator |
20:57:00 | flaviu | ok |
20:59:37 | * | dom96_ joined #nimrod |
21:00:02 | gokr1 | Araq: I know, but ... I kinda got a bit lost in that selectors code. |
21:02:23 | * | Ven quit (Quit: My MacBook has gone to sleep. ZZZzzz…) |
21:03:31 | Araq | gokr1: well let's ask dom96_ .... dom96_ ? |
21:03:57 | gokr1 | :) |
21:05:14 | * | itsmeront joined #nimrod |
21:05:18 | * | ldlework joined #nimrod |
21:05:23 | Araq | hi itsmeront welcome |
21:05:31 | Araq | hi ldlework welcome |
21:05:43 | dom96_ | gokr1: I offered to help you earlier... |
21:05:45 | itsmeront | Thanks! |
21:05:47 | Araq | ping reactormonk |
21:05:48 | dom96_ | What's the problem? |
21:05:58 | gokr1 | Hehe |
21:06:11 | gokr1 | No problem really - I am just a bit lost on the selectors front. |
21:06:24 | gokr1 | So let me ... show you my silly n00b code. |
21:06:54 | gokr1 | https://gist.github.com/gokr/df5b6de5d87ac535abf9 |
21:10:18 | gokr1 | Btw, I can turn that code into an article later - so if my comments in the code are wrong - do tell me. |
21:10:44 | gokr1 | I need to adjust that part where I do Socket() etc. And explain that spawn does do a deep copy of the arguments. |
21:11:04 | gokr1 | BUT... how do we throw some selectors magic into this? |
21:11:31 | gokr1 | I can probably solve it of course. |
21:16:40 | gokr1 | Btw, I have seen lots of code like "for x in items(y)" - how so? Why not "for x in y"? |
21:16:56 | gokr1 | Was it not automatic earlier perhaps? |
21:17:43 | Araq | gokr1: exactly |
21:22:56 | reactormonk | Araq, hm? |
21:23:59 | Araq | reactormonk: I'm beginning to think we need to release a 0.9.6.2 that contains the fixes for the regressions. |
21:24:40 | gokr1 | dom96_: I will fiddle with it, I can get back to you later :) |
21:24:46 | gokr1 | I found some good sample |
21:25:00 | Araq | or some other way to handle these beta vs final release issues |
21:25:40 | dom96_ | gokr1: You simply need to create a new PSelector object, register your socket(s) to it and then call select() on the object in a loop. |
21:25:50 | gokr1 | ok |
21:26:33 | Araq | dom96_: is that called 'select' even though it uses epoll? |
21:26:48 | gokr1 | I think the idea is to use that nomenclature polymorphically. |
21:27:00 | dom96_ | Araq: yes |
21:27:20 | gokr1 | But... PSelector? I am on bigbreak. Its Selector, right? |
21:27:26 | gokr1 | PSelector is deprecated I think |
21:27:29 | reactormonk | Araq, call them RC? |
21:27:59 | Araq | reactormonk: I dislike additions to a version number. |
21:28:56 | Araq | it's already a number with 3 components. usually one can use the patch number for these things. |
21:29:11 | * | nande joined #nimrod |
21:29:32 | Araq | but since the major number is frozen at 0 ... it all shifted |
21:39:56 | * | fowl joined #nimrod |
21:42:19 | * | mko quit (Ping timeout: 245 seconds) |
22:00:22 | * | itsmeront quit (Ping timeout: 246 seconds) |
22:02:52 | * | Etheco quit (Read error: Connection reset by peer) |
22:16:24 | * | Matthias247 quit (Read error: Connection reset by peer) |
22:19:10 | * | Joe_knock joined #nimrod |
22:26:43 | * | Mat3 quit (Quit: Verlassend) |
22:28:06 | dom96_ | gokr1: Maybe we forgot to change it. |
22:28:36 | Joe_knock | dom96_: Why the _? |
22:29:20 | dom96_ | Joe_knock: Because dom96 is my BNC which my desktop is connected to. |
22:30:07 | Joe_knock | are you living away from home now? dom96 |
22:30:10 | Joe_knock | dom96_ |
22:31:01 | dom96_ | Joe_knock: Yes. My desktop is here too, but i'm in the kitchen on my laptop. |
22:31:47 | gokr1 | dom96_: I think I got it working. |
22:31:52 | Joe_knock | if you dont mind me asking , what are you studying? |
22:32:13 | dom96_ | Joe_knock: Computer Science |
22:36:36 | * | jjilliann joined #nimrod |
22:36:59 | Joe_knock | dom96_: How similar is Jester to Flask? |
22:37:28 | * | jjilliann left #nimrod (#nimrod) |
22:38:52 | dom96_ | Joe_knock: Not sure. Never used Flask. But I assume it is quite similar. |
22:39:08 | Joe_knock | Are you using Jester in production anywhere? |
22:39:17 | Joe_knock | apart from the forum |
22:40:00 | dom96_ | nimbuild |
22:40:47 | dom96_ | apart from that no |
22:40:55 | dom96_ | nothing is using the new async jester yet |
22:41:00 | dom96_ | but the forum will soon |
22:41:37 | * | Jessin quit (Quit: Leaving) |
22:41:39 | Joe_knock | I'm keen to get started, but I'm waiting on a stable build of nim |
22:42:08 | * | xenagi joined #nimrod |
22:43:52 | * | Jesin joined #nimrod |
22:46:19 | * | Etheco joined #nimrod |
22:49:14 | * | Jesin quit (Quit: Leaving) |
22:53:16 | * | Jesin joined #nimrod |
22:56:44 | * | BlaXpirit quit (Quit: Quit Konversation) |
22:57:08 | * | dapz joined #nimrod |
22:57:58 | * | ehaliewicz joined #nimrod |
23:05:14 | gokr1 | Ok, so I do have a new spawningserver that uses the Selector (=epoll in Linux) |
23:06:58 | * | dapz quit (Quit: My MacBook has gone to sleep. ZZZzzz…) |
23:08:40 | * | dapz joined #nimrod |
23:09:31 | gokr1 | I am hammering it now - its nice to see all my 4 cores go up to around 50% while I do this. Memory is rock steady, nothing changes on the spawningserver. |
23:10:17 | gokr1 | I wonder what tool can show how a process spreads out on the cores? |
23:10:45 | * | flaviu quit (Read error: Connection reset by peer) |
23:12:31 | * | flaviu joined #nimrod |
23:13:17 | flaviu | gokr1: perf? |
23:13:23 | gokr1 | Ah, yeah. So spawningserver (threadpool) spreads out with about... 40 threads it seems. |
23:13:35 | flaviu | Not sure that it exposes it directly, but I'm 99% sure it stores that data |
23:13:38 | gokr1 | But the top 5 are taking most of the load. |
23:13:47 | gokr1 | I found some tricks :) |
23:24:05 | flaviu | gokr1: Mind sharing those tricks? |
23:24:24 | gokr1 | http://stackoverflow.com/questions/3342889/how-to-measure-separate-cpu-core-usage-for-a-process |
23:24:38 | gokr1 | I ended up using the little basj script at the bottom. |
23:24:41 | gokr1 | bash. |
23:24:53 | * | Trustable quit (Quit: Leaving) |
23:25:09 | gokr1 | I will gist my latest code too. |
23:28:07 | * | dom96_ quit (Ping timeout: 272 seconds) |
23:39:06 | * | dapz quit (Quit: My MacBook has gone to sleep. ZZZzzz…) |
23:39:31 | gokr1 | Current code if anyone is interested: https://gist.github.com/gokr/bc1f8a7e4a59fcf38501 |
23:42:29 | flaviu | I don't understand what discard OSError() is supposed to do. |
23:42:39 | flaviu | I'm fairly certain that's a no-op |
23:42:49 | gokr1 | oh, not sure :) |
23:43:22 | gokr1 | Hmmm, what did it say earlier... |
23:43:45 | gokr1 | Not sure why I threw in discard there. |
23:44:01 | flaviu | Because it gave you an error? |
23:44:18 | flaviu | s/discard OSError()/raise/ works as expected |
23:45:07 | flaviu | Nice, it works! |
23:46:51 | * | dapz joined #nimrod |
23:53:58 | gokr1 | Yeah, that OSError - no idea. I changed that. The discard was because nim told me to :) But I am not sure why I copied in "OSError()". I updated the gist - that must be better. |
23:54:16 | gokr1 | So now it does try: finally: to close in the handle proc if something barfs. |
23:54:24 | flaviu | well, now you're just throwing away errors |
23:54:37 | * | dom96_ joined #nimrod |
23:54:46 | gokr1 | And in listen I just close the socket for good measure. |
23:55:23 | gokr1 | I noted that... if you don't - and the server bombs out for some reason - then the port is unavailable for like 20 seconds or so :) |
23:55:39 | flaviu | Yep, but you should re-throw the exception |
23:55:58 | gokr1 | oh, using raiseOSError(lastOSError()) or ? |
23:56:02 | * | Etheco quit (Quit: Leaving) |
23:56:07 | flaviu | for some reason that port was unavailable, but I didn't know because the error was lost |
23:56:09 | gokr1 | Or some other thing. |
23:56:17 | flaviu | just using `raise` works just as well |
23:56:29 | gokr1 | ok, I haven't read up on this specific part |
23:56:40 | flaviu | lol, I just discovered it now too |
23:56:46 | gokr1 | So you just call raise? |
23:56:49 | flaviu | yep |
23:56:59 | * | gokr1 checking manual.... |
23:57:02 | flaviu | Works for me at least. It could be totally wrong |