01:06 <+bridge> [ddnet] @heinrich5991 have a minute? 01:06 <+bridge> [ddnet] yes 01:06 <+bridge> [ddnet] Q: `let caps = re.captures(message);` 01:06 <+bridge> [ddnet] I want to do something if either `caps.is_none()` or `caps.unwrap().len() < 3`, how best to write that? 01:07 <+bridge> [ddnet] need access to the elements then? 01:07 <+bridge> [ddnet] or just want to get rid of the unwrap? 01:07 <+bridge> [ddnet] `caps.map(|c| c.len() < 3).unwrap_or(true)` 01:07 <+bridge> [ddnet] If it's neither of these cases I want to unwrap 01:07 <+bridge> [ddnet] ah 01:08 <+bridge> [ddnet] this is an early return 01:08 <+bridge> [ddnet] I believe slice patterns are stable 01:09 <+bridge> [ddnet] hmm 01:09 <+bridge> [ddnet] ```rust 01:09 <+bridge> [ddnet] let (x, y, z, rest) = match re.captures(message) { 01:09 <+bridge> [ddnet] Some([x, y, z, ..rest]) => (x, y, z, rest), 01:09 <+bridge> [ddnet] _ => return, 01:09 <+bridge> [ddnet] } 01:09 <+bridge> [ddnet] ``` 01:09 <+bridge> [ddnet] doesn't really look nice :/ 01:10 <+bridge> [ddnet] Yeah I've been having a lot of annoying cases with error handling like this recently 01:10 <+bridge> [ddnet] what do you want to return in case of None or len() < 3? 01:11 <+bridge> [ddnet] the same thing? does the function return a Result? 01:12 <+bridge> [ddnet] In case of None or len < 3 I call a function and I return, the function returns nothing 01:13 <+bridge> [ddnet] you do need access to the first three elements, right? 01:13 <+bridge> [ddnet] if so, I don't really see anythign better than the ugly match above 01:13 <+bridge> [ddnet] I don't inside the condition 01:14 <+bridge> [ddnet] I obv need the 3 elements after I've confirmed they exist 01:14 <+bridge> [ddnet] yea, I don't see anything better than the above 01:14 <+bridge> [ddnet] tell me what you went with 😉 01:14 <+bridge> [ddnet] this is not a threat, I'm just interested. I'm not attached to my solution 01:15 <+bridge> [ddnet] `if let None | Some(0..=2) = caps.map(|m| m.len()) { ... }` someone on the rust discord was mentioning this 01:15 <+bridge> [ddnet] don't think it works out but it's interesting 01:16 <+bridge> [ddnet] huh, interesting 01:16 <+bridge> [ddnet] you don't get access to the `x` in `Some(x)` though 01:36 <+bridge> [ddnet] @heinrich5991 https://paste.pr0.tips/jR here is what I came up with, it's a tad fugly but it'll have to do for now 01:37 <+bridge> [ddnet] I really didn't feel like moving the error handling upwards to use `?` 01:37 <+bridge> [ddnet] ah, I like the filter 🙂 01:37 <+bridge> [ddnet] the idea was definitely from the guy in the rust discord 01:38 <+bridge> [ddnet] but he wanted to sell me more robust error handling 01:38 <+bridge> [ddnet] and I really am not in the mood right now 01:39 <+bridge> [ddnet] ^^ 09:34 <+bridge> [ddnet] https://github.com/fstd/pstd 09:34 <+bridge> [ddnet] > - The paste IDs we hand out start as 2-letter permutations of [A-Za-z0-0] 09:34 <+bridge> [ddnet] 09:34 <+bridge> [ddnet] 0-0? 09:53 <+bridge> [ddnet] @TsFreddie\: ? 09:53 <+bridge> [ddnet] oh 0-0 09:53 <+bridge> [ddnet] ye go fix 09:54 <+bridge> [ddnet] its a typo of 0-9 as you can see in this sample paste including a 9 https://paste.zillyhuhn.com/69 09:54 <+bridge> [ddnet] hihih 69 09:55 <+bridge> [ddnet] :tee_thinking: 09:58 <+bridge> [ddnet] when make pr @TsFreddie ? 09:58 <+bridge> [ddnet] how about never 09:59 <+bridge> [ddnet] ass 09:59 <+bridge> [ddnet] thenn ill do it 09:59 <+bridge> [ddnet] ye. glory awaits 10:04 <+bridge> [ddnet] you did it 💯, proud of you 10:04 <+bridge> [ddnet] ofc 11:17 <+bridge> [ddnet] @Learath2 what rust sv r u in? 11:17 <+bridge> [ddnet] i couldnt find u on the official one 11:17 <+bridge> [ddnet] :pepeH: 11:42 <+bridge> [ddnet] @Ryozuki https://discord.gg/rust-lang-community 12:43 <+bridge> [ddnet] > 7. If you come here for the game Rust, you will be kicked without warning. 12:47 <+bridge> [ddnet] add that to ddnet rules 13:30 <+bridge> [ddnet] 7. If you come here for the game Teeworlds, you will be kicked without warning. 13:30 <+bridge> [ddnet] :monkalaugh: 14:00 <+bridge> [ddnet] @heinrich5991 hm, could moving the tee a bit be acceptable? 14:01 <+bridge> [ddnet] I guess the idea is that being blocked from changing the team due to this is annoying 14:01 <+bridge> [ddnet] I agree with that 14:02 <+bridge> [ddnet] I can't immediately see problems with it, but it sounds icky, and it sounds like something that might be exploited on its own 14:02 <+bridge> [ddnet] I could reduce the range where it blocks you from joining a team, e.g. only block exactly stacking tees 14:13 <+bridge> [ddnet] I solved this by adding 0.2f to the y vel 14:13 <+bridge> [ddnet] minus* 14:14 <+bridge> [ddnet] Adding to velocity sounds dangerous somehow, but nudging the position should be relatively safe? 14:14 <+bridge> [ddnet] yea 17:24 <+bridge> [ddnet] > the trait `Encode<'_, Sqlite>` is not implemented for `u64` 17:24 <+bridge> [ddnet] If only sqlx was half as mature as it pretended to be 😛 17:27 <+bridge> [ddnet] Guess I'll just store everything as strings instead 17:31 <+bridge> [ddnet] @Learath2 i think sqlite doesnt have unsigned 17:31 <+bridge> [ddnet] https://cdn.discordapp.com/attachments/293493549758939136/865254213830836224/unknown.png 17:31 <+bridge> [ddnet] i guess thats why they dont impl it 17:31 <+bridge> [ddnet] 😛 17:32 <+bridge> [ddnet] https://cdn.discordapp.com/attachments/293493549758939136/865254458174865448/unknown.png 17:32 <+bridge> [ddnet] see 17:32 <+bridge> [ddnet] its deliberate 17:32 <+bridge> [ddnet] https://cdn.discordapp.com/attachments/293493549758939136/865254563983917096/unknown.png 17:32 <+bridge> [ddnet] hmm 17:32 <+bridge> [ddnet] xd 17:32 <+bridge> [ddnet] idk 17:32 <+bridge> [ddnet] hm, sqlite3 C interface clearly allows you to get 64b values and store them 17:33 <+bridge> [ddnet] `sqlite3_value_int64` 17:33 <+bridge> [ddnet] thats not uin64 tho 17:33 <+bridge> [ddnet] uint64* 17:34 <+bridge> [ddnet] https://cdn.discordapp.com/attachments/293493549758939136/865254934097035284/unknown.png 17:34 <+bridge> [ddnet] sqlite doesnt have unsigned values at all 17:34 <+bridge> [ddnet] Hm, you can store an 64 bit unsigned in a 64 bit signed. Sqlite doesn't even support different types at all internally 17:34 <+bridge> [ddnet] everything is a i64 17:35 <+bridge> [ddnet] The only value types in sqlite internally is 64b signed integer, 64b ieee float, string, blob and null iirc 17:35 <+bridge> [ddnet] Anyway, they can indeed implement a u64 one, I think it's just an oversight 17:35 <+bridge> [ddnet] i guess 17:35 <+bridge> [ddnet] open a pr 17:36 <+bridge> [ddnet] or issue 17:36 <+bridge> [ddnet] the good thing of open source 17:36 <+bridge> [ddnet] :monkalaugh: 17:36 <+bridge> [ddnet] I will give it a go after I finish up this mess 17:36 <+bridge> [ddnet] https://github.com/launchbadge/sqlx/issues/499 17:38 <+bridge> [ddnet] @Learath2 isnt it a bit pointless to do everything async and paralel to end up using sqlite, which is not paralel at all from my understanding 17:38 <+bridge> [ddnet] concurrent* 17:39 <+bridge> [ddnet] The plan wasn't to use sqlite, that's another limitation of sqlx that sort kicked me in the gut 😛 17:39 <+bridge> [ddnet] ? 17:39 <+bridge> [ddnet] sqlx supports psql and mysql too 17:39 <+bridge> [ddnet] The plan was to use the `Any` backend and I was going to use sqlite to test locally so I don't have to set up database servers 17:40 <+bridge> [ddnet] However, the Any backend has very very weird interaction with the query! macro, as in it doesn't respect the DATABASE_URI at all 17:41 <+bridge> [ddnet] So I ended up scrapping any hope of keeping this generic and just finished it up in the interest of getting the immediate need for a working bot satisfied 17:43 <+bridge> [ddnet] The new version I'm planning will probably use diesel, which works a little better in the genericity department but suffers from having very meh async support 17:43 <+bridge> [ddnet] very meh as in it doesnt have 17:43 <+bridge> [ddnet] there are 3rd party crates to help with it atleast 17:44 <+bridge> [ddnet] https://github.com/NyxCode/ormx 17:44 <+bridge> [ddnet] doesnt seem very maintained but it is there 17:44 <+bridge> [ddnet] xd 17:44 <+bridge> [ddnet] i personally use sqlx and generate stuff with this https://github.com/edg-l/modelizer 17:44 <+bridge> [ddnet] it is very tailored to my needs tho 17:44 <+bridge> [ddnet] I might also say fuckit and just do all of the concurrency by hand 17:45 <+bridge> [ddnet] why not, in rust u can do it without fear 17:45 <+bridge> [ddnet] :greenthing: 17:45 <+bridge> [ddnet] u just have to take care of possible deadlocks 17:45 <+bridge> [ddnet] Anyway, I need to finish this first, after we have a working bot I can work on making a clean bot 17:46 <+bridge> [ddnet] async is for bitches 17:46 <+bridge> [ddnet] :poggers: 17:47 <+bridge> [ddnet] I'm actually on the fence with async aswell, I'm sure it utilizes the cpu better than I could by hand but it is completely missing some of the context we as programmers have 17:47 <+bridge> [ddnet] I wonder how a task just hopping across workers affects performance, how it plays with cache locality etc.. 17:48 <+bridge> [ddnet] idk 17:48 <+bridge> [ddnet] for me async backends are a black box 17:50 <+bridge> [ddnet] You should read up on how rust does async, it's actually fairly interesting how the runtimes manage their tasks 17:50 <+bridge> [ddnet] i should 17:51 <+bridge> [ddnet] <513> hi, why after that when such information as the IP address, the list of servers, etc. disappears? It is updated anew as if it has been cleaned 17:51 <+bridge> [ddnet] <513> https://cdn.discordapp.com/attachments/293493549758939136/865259323604336710/unknown.png 17:52 <+bridge> [ddnet] wut is strstr 17:52 <+bridge> [ddnet] so long since i dont touch ddnet code 17:52 <+bridge> [ddnet] > Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1. 17:52 <+bridge> [ddnet] @Ryozuki Q: When you want to store a type without an encode/decode implementation in sqlx, what do you do? Do you implement it for yourself or do you convert to a type it understands? 17:53 <+bridge> [ddnet] @Learath2 i never found myself in that situation, is this for a type made by a crate u dont control? 17:53 <+bridge> [ddnet] I'm not quite sure how your code relates to your question, I don't really get the question either, can you try to rephrase? 17:53 <+bridge> [ddnet] One type I created, one for a crate I don't control 17:54 <+bridge> [ddnet] can u show me the type u made 17:54 <+bridge> [ddnet] usually types are made of other types and those simpler types impl the encode decode right? so u should just derive fromrow or smth? 17:54 <+bridge> [ddnet] It's an enum of two types from a crate I don't control 17:54 <+bridge> [ddnet] hmm 17:55 <+bridge> [ddnet] <513> I commented on this part when, and there were no problems, but if I use this, then everything works, but there is a problem. I go to the menu and there is no selected server and all the information is loaded again 17:55 <+bridge> [ddnet] The types from the crate I don't control cleanly map to u64 and I don't mind discarding the type information on the enum while storing, I can derive it again when loading 17:56 <+bridge> [ddnet] <513> https://cdn.discordapp.com/attachments/293493549758939136/865260614733266984/unknown.png 17:57 <+bridge> [ddnet] i guess i would impl Decode but maybe its not worth 17:57 <+bridge> [ddnet] then u would have to do select x as ": MyType" (or _) if u use the macros iirc 17:59 <+bridge> [ddnet] Mh, it doesn't really happen for me. If I join a server and check the ingame browser the selected server is still there 17:59 <+bridge> [ddnet] then u would have to do `select x as ": MyType" `(or _) if u use the macros iirc 17:59 <+bridge> [ddnet] Did you change something in the code that could break this? 18:00 <+bridge> [ddnet] <513> I provided a screenshot of the code above, which is why this problem occurs, I change my color or the like, after which this happens 18:00 <+bridge> [ddnet] then u would have to do `select x as "x: MyType" `(or _) if u use the macros iirc 18:01 <+bridge> [ddnet] <513> maybe because I change it directly g_Config.m_ClPlayerColorBody 18:02 <+bridge> [ddnet] https://dalek.rs/ 18:02 <+bridge> [ddnet] omg 18:03 <+bridge> [ddnet] i love whoever made this 18:03 <+bridge> [ddnet] and they use rust 18:03 <+bridge> [ddnet] im a doctor who fan 18:03 <+bridge> [ddnet] :monkaS: 18:03 <+bridge> [ddnet] https://cdn.discordapp.com/attachments/293493549758939136/865262402538438656/unknown.png 18:05 <+bridge> [ddnet] their ascii thing is messed up 18:05 <+bridge> [ddnet] Ah I know what you broke 18:05 <+bridge> [ddnet] no its not 18:05 <+bridge> [ddnet] 64 is way too much, playerskin is only 24 characters. Instead of 64 use `sizeof(g_Config.m_ClPlayerSkin)` 18:05 <+bridge> [ddnet] its some kind of wave 18:06 <+bridge> [ddnet] @513 what are you making btw? 18:06 <+bridge> [ddnet] a bot 18:06 <+bridge> [ddnet] :monkalaugh: 18:06 <+bridge> [ddnet] idk why anyone not purple asking for code is always a botter 18:06 <+bridge> [ddnet] hopefully not, it'd be very sad if I helped a botter 😛 18:06 <+bridge> [ddnet] its always ppl who are never active in this discord 18:06 <+bridge> [ddnet] probs using 2nd account maybe 18:07 <+bridge> [ddnet] <513> skin stealer it's bot? 18:07 <+bridge> [ddnet] Looks like a remote controlled tee with the ability to change colors on messages, didn't look very dangerous to me 😛 18:07 <+bridge> [ddnet] haha 18:07 <+bridge> [ddnet] u will look fishy to anyone if u use it 18:07 <+bridge> [ddnet] and they will probs call a mod and ban u 18:08 <+bridge> [ddnet] cuz u will be fishy 18:08 <+bridge> [ddnet] Eeeeeh, not really that problematic by itself but mods will be suspicious yes 18:08 <+bridge> [ddnet] actual bot clients already have that feature 18:09 <+bridge> [ddnet] might async be overkill for a discord bot? 18:09 <+bridge> [ddnet] i guess it depends on the scale 18:09 <+bridge> [ddnet] if its used for this sv i guess its overkill 18:09 <+bridge> [ddnet] maybe this is a more general question 18:09 <+bridge> [ddnet] but maybe the discord library is not async but implements sharding 18:10 <+bridge> [ddnet] when does async outperform spawning a couple of threads 18:10 <+bridge> [ddnet] idk 18:10 <+bridge> [ddnet] Yeah very tough question too, depends a lot on the runtime and how good it is 18:10 <+bridge> [ddnet] i think async threads are way cheaper 18:10 <+bridge> [ddnet] than os threads 18:10 <+bridge> [ddnet] tokio claims this 18:10 <+bridge> [ddnet] <513> big ty 18:11 <+bridge> [ddnet] @Ryozuki got a link? 18:11 <+bridge> [ddnet] > Tasks are light weight. Because tasks are scheduled by the Tokio runtime rather than the operating system, creating new tasks or switching between tasks does not require a context switch and has fairly low overhead. Creating, running, and destroying large numbers of tasks is quite cheap, especially compared to OS threads. 18:11 <+bridge> [ddnet] https://docs.rs/tokio/1.8.1/tokio/task/index.html 18:11 <+bridge> [ddnet] hm, doesn't have numbers 18:11 <+bridge> [ddnet] I'd imagine it varies wildly by OS 18:12 <+bridge> [ddnet] I guess it's fair to say async can saturate a cpu easier than threads, since with enough tasks it can ensure every thread is working 18:14 <+bridge> [ddnet] Not really quite sure tbf, but async code is a good abstraction over the rather complicated issue of threading an application. Atleast in the sense that it makes it easier for a programmer to be efficiently using resources without having to think too much about it 18:14 <+bridge> [ddnet] I see 18:14 <+bridge> [ddnet] so the "only" downside is rust's immature async support? 18:14 <+bridge> [ddnet] thats how i feel about it too 18:15 <+bridge> [ddnet] Well I think so, I'm sure there are people far more qualified than me to comment on this. 18:16 <+bridge> [ddnet] As I said ^^. I'm not quite sure if the runtimes are good enough at moving tasks around and inferring relationships between them. 18:22 <+bridge> [ddnet] ah, apparently async is also a memory usage optimization 18:32 <+bridge> [ddnet] I have a feeling I'm still holding a lot of rust wrong, but it is fun to learn more 18:32 <+bridge> [ddnet] nice 🙂 18:32 <+bridge> [ddnet] e.g. this https://paste.pr0.tips/hH just doesn't look quite right 😄 18:33 <+bridge> [ddnet] I still find it weird that you use a `RwLock<()>` ^^ 18:33 <+bridge> [ddnet] maybe it's the library interface just not being flexible enough, maybe it's me not really holding it correctly 18:34 <+bridge> [ddnet] Well if you have a minute we can try to discuss it, I really don't see how else to make this safe 18:34 <+bridge> [ddnet] I think we discussed it before, but I'm interested in why we didn't come up with a better solution 18:34 <+bridge> [ddnet] ah, was it that sqlx doesn't support transactions? 18:34 <+bridge> [ddnet] Well let me give you a concrete example I couldn't reason about and thus think I have to lock the entire table somehow 18:37 <+bridge> [ddnet] Tester A approves map M, Tester B approves map M at the same time. Task T_A launches and gets the row corresponding to the submission from the db. Before Task T_A gets to mark it as evaluated, Task T_B also gets the row. Now we have two threads trying to approve the same map 18:38 <+bridge> [ddnet] can you start transactions? 18:38 <+bridge> [ddnet] I can, but I'm not completely sure what kind of guarantees that gives me. Afaik sqlite doesn't even have the kind of transaction I require 18:39 <+bridge> [ddnet] if I read the docs correctly, you can start a IMMEDIATE transaction, and that gives you exclusive write access 18:40 <+bridge> [ddnet] sqlx doesn't even expose this to me 18:41 <+bridge> [ddnet] So I settled for a rwlock that isn't really attached to any type and used the usual "advisory lock" pattern 18:41 <+bridge> [ddnet] but you can start a transaction, apparently 18:41 <+bridge> [ddnet] I can but I don't see any api for what type of transaction gets started 18:41 <+bridge> [ddnet] I don't know which of these transactions it is, but all three are okay for you 18:42 <+bridge> [ddnet] When I begin a transaction doesn't that lock the entire db though? If say I do an immediate one 18:42 <+bridge> [ddnet] it locks the DB for writing 18:42 <+bridge> [ddnet] not reading 18:43 <+bridge> [ddnet] reads will use the state of the DB before your transaction 18:43 <+bridge> [ddnet] And if someone wants to write? 18:43 <+bridge> [ddnet] what I'm more worried about is how to detect that you can write again 18:43 <+bridge> [ddnet] that will be blocked until your transaction finishes 18:44 <+bridge> [ddnet] The tables here are also independent, locking the entire db is sort of unnecessary, but I could do that for cleaner codes sake 18:44 <+bridge> [ddnet] I see 18:44 <+bridge> [ddnet] what does your sqlite library do with SQLITE_BUSY errors? 18:45 <+bridge> [ddnet] let me take a look 18:46 <+bridge> [ddnet] Ok so first of all https://github.com/launchbadge/sqlx/issues/481 means I'm right about sqlx not exposing the different kinds of transactions yet 18:47 <+bridge> [ddnet] I'll take a look at the source to see what they are doing with the `SQLITE_BUSY` 18:54 <+bridge> [ddnet] I also took a look 18:54 <+bridge> [ddnet] apparently waiting, and then returning SQLITE_BUSY to the user after (by default) 5 seconds 18:58 <+bridge> [ddnet] Hm, where did you get that? I was just about to conclude that it just returns an error like any other error from the db 18:58 <+bridge> [ddnet] I think the 5s might be on the sqlite side? 18:58 <+bridge> [ddnet] I grepped for busy (case-insensitive) 18:58 <+bridge> [ddnet] it asks sqlite3 to do the waiting 18:58 <+bridge> [ddnet] but it sets its own default value (5s) 18:58 <+bridge> [ddnet] grep for `sqlite3_busy_timeout` 18:59 <+bridge> [ddnet] ah, found it 19:00 <+bridge> [ddnet] Hm, that is quite annoying to leave to the poor user to handle, it's also something I can't wait on effectively 19:01 <+bridge> [ddnet] I guess you handle it like other errors? 19:01 <+bridge> [ddnet] what are you gonna do, wait longer? ^^ 19:01 <+bridge> [ddnet] If I could start an immediate transaction I could busy loop until I get to start one, but there is no guarantee for me to get one, by sheer luck one task could starve forever 19:02 <+bridge> [ddnet] I actually wouldn't mind a task sleeping until the database isn't busy, if there was any wake up guarantee 19:04 <+bridge> [ddnet] Yeah I can't really drop these locks atleast until they expose immediate transactions 19:05 <+bridge> [ddnet] When they have immediate transactions I can get the row, immediately modify it to show the new state and commit so I don't lock too long, and T_B never ends up getting the exact same row as T_A 19:06 <+bridge> [ddnet] This does sound very wrong though, immediate transactions are a sqlite thing. How do people ensure this kind of thing doesn't happen in mysql and psql? 19:06 <+bridge> [ddnet] you have other things that write to the db, no? 19:06 <+bridge> [ddnet] then you can probably still get SQLITE_BUSY errors 19:06 <+bridge> [ddnet] also transactions, probably? why do you need an IMMEDIATE transaction, specifically? 19:07 <+bridge> [ddnet] A non immediate transaction means I can get a busy within the transaction 19:07 <+bridge> [ddnet] Busy within the transaction means I need wrappers for all my queries that busy loop until they can get their change in 19:08 <+bridge> [ddnet] With immediate transactions I can busy loop just once to get my exclusive access 19:08 <+bridge> [ddnet] I see 19:08 <+bridge> [ddnet] idk maybe there is a way turn this into a non-racy pattern, but I'm not seeing it 19:09 <+bridge> [ddnet] I basically need an atomic read-modify-write but in sql 19:09 <+bridge> [ddnet] does rwlock guarantee that you don't starve btw? probably not, how would it 19:09 <+bridge> [ddnet] but the transcation provides this(?) 19:10 <+bridge> [ddnet] you might just need to retry 19:11 <+bridge> [ddnet] tokio rwlocks ensure writers are not starved 19:11 <+bridge> [ddnet] ah nice 19:11 <+bridge> [ddnet] and they are fair due to using a fifo queue 19:12 <+bridge> [ddnet] is this really acceptable? I'd basically need busy waiting, with no guarantee that I'd ever get through 19:12 <+bridge> [ddnet] > This is in contrast to the Rust standard library’s `std::sync::RwLock`, where the priority policy is dependent on the operating system’s implementation. 19:13 <+bridge> [ddnet] I guess there should be some kind of "wait for transaction" sqlite3 command 19:14 <+bridge> [ddnet] > SQLite is not terribly helpful when it comes to concurrency. By default, it does not even provide any fairness guarantees (although you can write them yourself as long as your concurrency is happening within the same process). 19:14 <+bridge> [ddnet] https://stackoverflow.com/a/25266277 19:15 <+bridge> [ddnet] I guess my rwlock qualifies as "write them yourself". An outside process is a bit of an issue but I currently don't have any 19:15 <+bridge> [ddnet] you'd need a write lock for the whole db though, not just this table(?) 19:16 <+bridge> [ddnet] Hm, I guess it is actually possible that a two threads smack in the middle of a query collide and since sqlite doesn't allow concurrent writes even to discrete tables this would break 19:17 <+bridge> [ddnet] okay I guess my attempt at this isn't exactly safe either 19:18 <+bridge> [ddnet] eh, this is just a field I'm not well versed enough to do this properly 19:20 <+bridge> [ddnet] concurrency is hard who would have said 19:21 <+bridge> [ddnet] The documentation I read about this really exposes a very uncomfortable interface. With essentially each and every query having to be wrapped in a `while(rc == SQLITE_BUSY)` and that sounds absolutely insane to me 19:22 <+bridge> [ddnet] hm 19:23 <+bridge> [ddnet] I'd think it's the transactions that need to be wrapped in that 19:23 <+bridge> [ddnet] not individual queries 19:23 <+bridge> [ddnet] but still annoying 19:23 <+bridge> [ddnet] for an immediate transaction that is true, but for other ones I'm not so sure 19:25 <+bridge> [ddnet] there are cases where you need to redo your entire (also non-immediate) transaction 19:25 <+bridge> [ddnet] e.g. if another connection did writes to the DB since you read 19:25 <+bridge> [ddnet] um, how is that signalled? 19:27 <+bridge> [ddnet] apparently with `SQLITE_BUSY_SNAPSHOT` if extended error codes are enabled 19:27 <+bridge> [ddnet] otherwise `SQLITE_BUSY` 19:28 <+bridge> [ddnet] https://activesphere.com/blog/2018/12/24/understanding-sqlite-busy 19:29 <+bridge> [ddnet] This one actually sounds useful, in my usecase 19:30 <+bridge> [ddnet] One thing this entire adventure revealed is that database systems are much more strict than I initially thought 19:30 <+bridge> [ddnet] can you elaborate what you mean by "strict"? 19:32 <+bridge> [ddnet] Well in the case of sqlite it supports concurrency in a very specific way. Whether tables depend on eachother or not writing is only allowed for one connection at a time. Whether your transaction cares about other writes during it or not you are getting a `SQLITE_BUSY_SNAPSHOT` 19:33 <+bridge> [ddnet] I see, so strict in the meaning of "not supporting many options, e.g. many concurrency models" 19:33 <+bridge> [ddnet] Yes, I guess that's what I had in mind 19:34 <+bridge> [ddnet] @ScReeNy what do you mean by "unlock" finishing? 19:34 <+bridge> [ddnet] @ScReeNy what do you mean by "unlock finishing"? 19:34 <+bridge> [ddnet] that you join team 0 after finishing in team? 19:36 <+bridge> [ddnet] yes if you finish in an unlocked team you join team 0 and can stack 19:37 <+bridge> [ddnet] and this can be abused? 19:38 <+bridge> [ddnet] by this you can stack tees in one tile and do a stack hammer 19:38 <+bridge> [ddnet] idk if this actually gets used, i only did once but it got fixed 19:38 <+bridge> [ddnet] doesnt work on many maps 19:39 <+bridge> [ddnet] ok, so that might need fixing, too 19:39 <+bridge> [ddnet] how about allowing people to join team 0 while standing on the finish tile? 19:39 <+bridge> [ddnet] and automatically letting them join team 0 if there's space during finish 19:40 <+bridge> [ddnet] hm, not much different than always allowing them to join team0 after finishing 19:40 <+bridge> [ddnet] after all, the last tee might just wait for everyone to get into position before finishing 19:40 <+bridge> [ddnet] InnoDB locking in mysql seems much more flexible allowing table and even row level locks 19:41 <+bridge> [ddnet] yes thats how you do it 19:41 <+bridge> [ddnet] well sqlite is supposed to be rly simple 19:42 <+bridge> [ddnet] so only joining people to t0 that are currently unblocked and allowing the rest to join t0 whenever they want would work @ScReeNy? 19:42 <+bridge> [ddnet] it is indeed, maybe picking one concurrency scheme and sticking to it does make it cleaner. afterall all the memory ordering stuff in atomics doesn't make it very easy to reason about them 19:44 <+bridge> [ddnet] if you count in unlock finish yes. This wont fix everything but at least shouldnt cause issues. 19:45 <+bridge> [ddnet] thanks. I'll post this to the issue if that's okay 🙂 19:46 <+bridge> [ddnet] sure 19:52 <+bridge> [ddnet] what do you call an identifier that lets you unambiguously identify which of two objects is newer, like a timestamp, but might be arbitrary data 19:52 <+bridge> [ddnet] version? 19:52 <+bridge> [ddnet] @Learath2? 🙂 19:53 <+bridge> [ddnet] serial is also common 19:53 <+bridge> [ddnet] interesting, haven't heard that before 19:53 <+bridge> [ddnet] well common is reaching, but I've seen it 😄 19:54 <+bridge> [ddnet] I'm trying to find a name for the "serial" of the info object sent by the game server to the master server 19:54 <+bridge> [ddnet] so that old lingering requests do not cause the masterserver to distribute outdated server info 19:54 <+bridge> [ddnet] Ah I think serial is perfect for that, it even implies the number will be increasing 19:54 <+bridge> [ddnet] `"info_serial"`? 19:55 <+bridge> [ddnet] the first time I heard serial was in context of dns zones btw, bind9 19:55 <+bridge> [ddnet] ah nice 19:55 <+bridge> [ddnet] sounds good to me 19:55 <+bridge> [ddnet] if it's used by bind9, it's probably the right term ^^ 19:58 <+bridge> [ddnet] maybe the `info_` is redundant? it's already part of the info after all, no? 19:58 <+bridge> [ddnet] hm, actually it is more metadata about the info than part of it 19:58 <+bridge> [ddnet] I put it next to the info 19:58 <+bridge> [ddnet] since the masterserver needs to interpret it 19:58 <+bridge> [ddnet] yeah, makes sense 19:59 <+bridge> [ddnet] oh, btw could you get a chance to look at the filtering issue @fokkonaut was having? 19:59 <+bridge> [ddnet] its basically fine again 19:59 <+bridge> [ddnet] ah true, should do that 19:59 <+bridge> [ddnet] it fixed itself? 19:59 <+bridge> [ddnet] i just need 128p support (for client info/clan/etc) 20:00 <+bridge> [ddnet] Yes, i said that from the beginning. if i send as much client infos as there are clients online, then it works 20:00 <+bridge> [ddnet] Oh, that's not fixing itself, you fixed it 20:00 <+bridge> [ddnet] afk food. will read afterwards 20:00 <+bridge> [ddnet] . 20:01 <+bridge> [ddnet] @heinrich5991 the master server doesn't really care how many players the server says it has now. Maybe it should? I think it's sane to allow incomplete ones, with maybe some ui indication that not all the info was sent 20:01 <+bridge> [ddnet] that sounds good 20:01 <+bridge> [ddnet] i guess 20:01 <+bridge> [ddnet] the masterserver does indeed not care about the number of players 20:02 <+bridge> [ddnet] it's just that the json (intentionally) has no player count field 20:02 <+bridge> [ddnet] no num_players and no num_clients 20:02 <+bridge> [ddnet] because that'd duplicate info from the players array 20:02 <+bridge> [ddnet] did you ever think about sv_server_info_per_second? 20:03 <+bridge> [ddnet] yes, I consider the current setup the backwards compatibility 20:03 <+bridge> [ddnet] But it's technically not duplicate info if we allow less playerinfo to be sent 20:03 <+bridge> [ddnet] sorry, but obviously not 20:03 <+bridge> [ddnet] that was just a hack (sv_server_info_per_second) 20:03 <+bridge> [ddnet] yea 20:03 <+bridge> [ddnet] but it fucks the info right now 20:03 <+bridge> [ddnet] client sorts it out 20:03 <+bridge> [ddnet] it'll get better 😉 I'm even working on it 20:03 <+bridge> [ddnet] i dont doubt 20:04 <+bridge> [ddnet] what are you doing? the server -> masterserver part? 20:04 <+bridge> [ddnet] yes 20:04 <+bridge> [ddnet] how do i open a file with fopen? absolute or relative path? 20:04 <+bridge> [ddnet] i cant seem to open it 20:04 <+bridge> [ddnet] either is fine 20:04 <+bridge> [ddnet] doesnt work lul 20:04 <+bridge> [ddnet] returns 0 20:04 <+bridge> [ddnet] ah no 20:04 <+bridge> [ddnet] im dumb 20:04 <+bridge> [ddnet] wrong var 20:05 <+bridge> [ddnet] lol how can i see stuff like this only when i ask here 20:05 <+bridge> [ddnet] xD 20:05 <+bridge> [ddnet] it's the same thing that happens when you call a professional to take a look at something 20:05 <+bridge> [ddnet] yea, immediately its clear 20:05 <+bridge> [ddnet] or pops to your eye 20:05 <+bridge> [ddnet] I had intermittent issues with electricity that never happened when the electrician is here 20:05 <+bridge> [ddnet] xD 20:06 <+bridge> [ddnet] I've decided the sanest way to do concurrency in sqlite is to treat SQLITE_BUSY as fatal, let the user retry 20:08 <+bridge> [ddnet] With the delays introduced by the human element the conflicts should be rare enough that handling them just makes the code dirty 20:27 <+bridge> [ddnet] https://beets.io/blog/sqlite-nightmare.html seems I wasn't the only one to resort to locking at language level for sqlite 20:55 <+bridge> [ddnet] Oh I'm an absolute goof, my locking doesn't even work at all 😄 20:59 <+bridge> [ddnet] Need to hold the lock longer, I guess I'll do a whole database lock and abstract over transactions 21:00 <+bridge> [ddnet] at that point you could put the db into the rwlock \o/ 21:02 <+bridge> [ddnet] I could indeed, even better would be to have 2 connections, one for writing and a pool for reading and a rwlock coordinating so I never have to deal with SQLITE_BUSY at all 21:07 <+bridge> [ddnet] what do the cool kids use for multithreading in ddnet these days? i remember using thread_init and also the pain i experienced with it? i want to issue some requests asynchonously and if possible also get the result 😄 21:07 <+bridge> [ddnet] jobs 21:07 <+bridge> [ddnet] (still painful though) 21:07 <+bridge> [ddnet] depends on your definition of pain a lot 😄 21:08 <+bridge> [ddnet] I mean it's not as trivial as futures maybe, but it's not much more painful than threading in just C/C++ 21:08 <+bridge> [ddnet] thanks, i will read into it 🙂 22:42 <+bridge> [ddnet] https://blog.crunchydata.com/blog/generating-json-directly-from-postgres 22:42 <+bridge> [ddnet] :o 22:50 <+bridge> [ddnet] <'faceless> Anyone does know java well, 22:50 <+bridge> [ddnet] <'faceless> Anyone does know java well? 22:51 <+bridge> [ddnet] ask your question 22:52 <+bridge> [ddnet] https://dontasktoask.com/ 22:52 <+bridge> [ddnet] this website fits so perfectly 22:52 <+bridge> [ddnet] and its always java 22:52 <+bridge> [ddnet] https://cdn.discordapp.com/attachments/293493549758939136/865335141458378772/unknown.png 22:52 <+bridge> [ddnet] :monkalaugh: 22:53 <+bridge> [ddnet] <'faceless> Yea but 22:53 <+bridge> [ddnet] no yeas 22:54 <+bridge> [ddnet] <'faceless> Bit operations 22:54 <+bridge> [ddnet] <'faceless> I have 12 tasks 22:54 <+bridge> [ddnet] <'faceless> And 4 of them made my brain... 22:54 <+bridge> [ddnet] idk the others but im not here to do ur homework xd 22:54 <+bridge> [ddnet] <'faceless> Just wanna ask for some advices 22:55 <+bridge> [ddnet] then ask 22:55 <+bridge> [ddnet] <'faceless> How can i make binary number higher bit to 0, with simple bit operations? 22:56 <+bridge> [ddnet] <'faceless> Onöy simple 22:56 <+bridge> [ddnet] | 0x80000000 22:56 <+bridge> [ddnet] <'faceless> Only simple 22:56 <+bridge> [ddnet] see, that doesnt even require java 22:56 <+bridge> [ddnet] <'faceless> Anyway 22:56 <+bridge> [ddnet] do you want to set the highest bit to 1? 22:57 <+bridge> [ddnet] <'faceless> I need to set the highest 1 to 0 22:57 <+bridge> [ddnet] <'faceless> With any number i scan 22:57 <+bridge> [ddnet] ah 22:57 <+bridge> [ddnet] you want to set the highest bit that is 1 to 0 22:59 <+bridge> [ddnet] ? 22:59 <+bridge> [ddnet] <'faceless> Yes, how to set the lower i know, how to set the 2nd, 3rd etc ik too, but if number changes its higher 1 from one rank to another 23:00 <+bridge> [ddnet] sorry, I don't understand what you say 23:00 <+bridge> [ddnet] can you give an example? 23:00 <+bridge> [ddnet] <'faceless> Ehm 23:00 <+bridge> [ddnet] <'faceless> So 23:00 <+bridge> [ddnet] <'faceless> I mean, i need a code which inverts higher 1 to 0 23:00 <+bridge> [ddnet] <'faceless> For example 23:01 <+bridge> [ddnet] <'faceless> 11000 i need to get 01000, and if number will be 10110000, so i need to convert a higher 1 as well, to 00110000 23:01 <+bridge> [ddnet] I see 23:02 <+bridge> [ddnet] so we can split up the problem into "find the index of the highest 1" and "set that 1 to 0" 23:02 <+bridge> [ddnet] <'faceless> Yea 23:02 <+bridge> [ddnet] <'faceless> But 23:02 <+bridge> [ddnet] <'faceless> Only with simple bit operations 23:02 <+bridge> [ddnet] how can you test whether the n-th bit is set? 23:02 <+bridge> [ddnet] say you have the number x 23:03 <+bridge> [ddnet] can you write java code that checks if the n-th bit is set? 23:03 <+bridge> [ddnet] <'faceless> If i know n i can use >>n 23:03 <+bridge> [ddnet] <'faceless> And using if, its 1 or 0 23:03 <+bridge> [ddnet] this expression doesn't contain x, it can't be the solution 23:04 <+bridge> [ddnet] ```java 23:04 <+bridge> [ddnet] static void checkNthBit(int x, int n) { 23:04 <+bridge> [ddnet] [...] 23:04 <+bridge> [ddnet] } 23:04 <+bridge> [ddnet] ``` 23:04 <+bridge> [ddnet] fill the function so it outputs "1" if the n-th bit of x is set and "0" otherwise 23:05 <+bridge> [ddnet] **void** :monkaS: 23:05 <+bridge> [ddnet] @Ryozuki I wanted it on stdout 23:05 <+bridge> [ddnet] ah 23:05 <+bridge> [ddnet] <'faceless> With void check yea, but what about using only ~, |, & or ^ and << >> 23:06 <+bridge> [ddnet] #define void int 23:06 <+bridge> [ddnet] use those 23:06 <+bridge> [ddnet] he asking u to do it 23:06 <+bridge> [ddnet] heinrich the good teacher 23:07 <+bridge> [ddnet] <'faceless> But i hadnt used english for a while, so im a bad explainer :( 23:07 <+bridge> [ddnet] whats ur main language 23:07 <+bridge> [ddnet] <'faceless> Rus 23:07 <+bridge> [ddnet] uh 23:07 <+bridge> [ddnet] sorry 23:07 <+bridge> [ddnet] java xd 23:07 <+bridge> [ddnet] xd 23:08 <+bridge> [ddnet] we dont have any rus dev that i know here 23:08 <+bridge> [ddnet] :monkaS: 23:08 <+bridge> [ddnet] <'faceless> Sad af 23:08 <+bridge> [ddnet] banzai is ukraine 23:09 <+bridge> [ddnet] BannZay* 23:27 <+bridge> [ddnet] how am I going to do the port forward check in the https masters? 23:27 <+bridge> [ddnet] I want to send a challenge that the game server has to include in its next register attempt 23:45 <+bridge> [ddnet] faceless можешь мне рассказать, я переведу 23:46 <+bridge> [ddnet] @'faceless 23:47 <+bridge> [ddnet] <'faceless> Да уже вроде вспомнил как на англ разговариватт 23:49 <+bridge> [ddnet] ping me if u need help 23:51 <+bridge> [ddnet] Hm, can we use the old protocol? or do you need something new?