wayland Oh! Lovely! Hi :) 00:06
tbrowder no, i was having some weird problem building raku and i shared a remote server with you to see if you could dup my problem
[Coke] ah. I don't remember what thge resolution on that was, sorry. 00:07
00:08 rmv joined, rmv left, rmv joined, guifa_ left
[Coke] ISTR I couldn't duplicate the issue. 00:08
if you're still having the issue, I can try a build. 00:09
(if you re-give me access)
tbrowder it wasn’t really resolved but i figured my system was really messed up. anyhoo, you showed me yr method for bldg raku from scratch and i didn’t save it 00:10
[Coke] I still recommend using rakubrew, but to build from scratch, I grab rakudo from git; pick a tag if you want a released version (or grab the source from the release itself on github), then "perl Configure --gen-nqp --gen-moar --install=path/to/install/directory && make install" 00:15
then add that path and that path/perl6/site/bin to your PATH. 00:16
then follow the install instructions on the readme for zef github.com/ugexe/zef 00:17
but rakubrew will do all that for you
00:21 rmv left
tbrowder ok, thanks. i’ll try the rakubrew route first 00:27
wayland .tell patrickb Where do I report bugs in Rainbow? If I use `RAKUDO_RAKUAST=1 zef install Rainbow` it fails. 00:55
tellable6 wayland, I'll pass your message to patrickb
[Coke] wayland: "zef info Rainbow | grep bugt" 00:56
wayland [Coke]: Oh, lovely! Thanks! 00:57
.tell pattrickb Don't worry, Coke showed me how to find your bugtracker. 01:01
tellable6 wayland, I'll pass your message to patrickb
01:05 guifa_ joined 01:51 hulk joined 01:52 kylese left 02:15 hulk left, kylese joined
simon_sibl timo: I added VM.own-up on ctrl-c, I added some note() and sleeps hoping to see more clear whats happening but it doesnt make sense to me, for example, the main file gets update from Downloader emitting, but in the log it shows that it first log the main file and then the Downlaoder ?? github.com/4zv4l/rbt/tree/testing I made a branch for testing if anyone wanna try to understand whats going on as well.. 02:32
for some reason when using RAKUDO_SCHEDULER_DEBUG=1 it doesnt seem to block 02:33
also for some reason the sleep() from the Peer.rakumod are respected but the ones from Downloader.rakumod arent respected..
ah I guess its because this fetch-peers is faulty and doesnt actually fetch more peers 02:35
02:48 camelia left 02:49 camelia joined 03:14 apogee_ntv left
Voldenet sleep and whenever don't mix 03:41
unless you really want to block everything in the app for N seconds 03:42
m: sub foo() { supply { sleep 1; say now - BEGIN now }}; react { whenever Supply.interval(.1).head(5) { whenever foo() { } } } 03:44
camelia 1.043771665
2.070991126
3.07236937
4.073811805
5.075045594
03:45
Voldenet instead, use `whenever Promise.in(3) { … }`
m: sub foo() { supply { whenever Promise.in(1) { say now - BEGIN now } }}; react { whenever Supply.interval(.1).head(5) { whenever foo() { } } }
camelia 1.055391862
1.138582385
1.237710739
1.337984193
1.437967536
Voldenet it's kinda foreign code style, because you say "to the event loop, attach another event", instead of "block the whole event loop for N seconds" 03:46
of course, LEAVE would work wrong too, it would leave the block immediately (since whenever attaches the event and leaves) 03:48
the style with whenever doesn't really use scheduler, it's just one big event loop underneath – despite complexity it makes everything single-threaded so you never need locks 03:57
but its complexity is the price 03:58
m: start { sleep 3; say ":(!"; exit; }; react { whenever Supply.interval(.1).head(5) { whenever supply { whenever 1 { die "why?" } } { QUIT { default { .say } } } } }; # this is surprising 04:02
camelia why?
in block at <tmp> line 1

why?
in block at <tmp> line 1

why?
in block at <tmp> line 1

why?
in block at <tmp> line 1

why?
in block at <tmp> line 1

:(!
04:03
Voldenet m: start { sleep 3; say ":(!"; exit; }; react { whenever Supply.interval(.1).head(5) { whenever supply { whenever Promise.in(0) { die "why?" } } { QUIT { default { .say } } } } }; # replacing immediately executed "die" into defered one works
camelia why?
in block at <tmp> line 1

why?
in block at <tmp> line 1

why?
in block at <tmp> line 1

why?
in block at <tmp> line 1

why?
in block at <tmp> line 1
Voldenet (btw, should that "die" really hang?) 04:30
(the one with `whenever 1`)
(QUIT handler seems to be attached and used, but for some reason the whole react blocks does something) 04:32
timo I think the program might be doing non-threadsafe things 04:37
Voldenet P 04:40
timo i think i've found a deadlock in the utf8 decoder 04:43
a regression i made in the latest release 04:44
cringe. mea culpa. 04:50
but if there are multiple threads running doing work, it should eventually cause a GC run and unblock this particular issue 04:56
I only(?) hit it before any actual connections have been established
Voldenet I've looked at the problem in that snippet of mine 04:57
github.com/rakudo/rakudo/blob/main...akumod#L20
shouldn't that Supplier be made before running tap? 04:58
05:00 hurufu joined
timo i don't know how all these callbacks actually work, and I've got a headache :| 05:04
Voldenet it's a bit too warm for this kind of work 05:05
timo share.firefox.dev/4vKOICE here, have a profile of rbt 05:08
Voldenet I like how 13% of Thread#8 is github.com/4zv4l/rbt/blob/aa07363a...akumod#L87 05:21
timo it's probably actually github.com/4zv4l/rbt/blob/main/lib...akumod#L87 05:22
Voldenet ah, okay
timo it goes through the entire channel and re-sends all entries, filtering maybe one of them out to use? 05:23
but only every 2 seconds I guess 05:24
Voldenet MVM_concblockingqueue_poll 05:25
yeah, that's `$!todo-chan.poll`
timo where did you get the 13% from?
Voldenet i.imgur.com/Vl9vLFC.png 05:26
samples count is not amazing
timo filtering by "rbt" is not going to get you very insightful results i don't think 05:27
we don't have stack traces of the raku-level frames, only ever the topmost one if it's jitted, and no record of what frame it is at all if it's not jitted, then it'll just be attributed to "MVM_interp_run" 05:28
and anything called by functions inside one of the rbt code files will just be attributed to the setting and such
Voldenet ah, this 13% is in relation to only filtered samples
timo that's why you only see 53 samples in total there
yeah
Voldenet `Promise.in(2).then: { self!request-work($conn) }` 05:29
this line scares me
timo do you think they might accumulate? 05:30
Voldenet if it even gets to the point of exceeding 50 attempts of todo-chan.poll 05:31
I'm not sure if they'd accumulate, but this has no exception handling, reads and writes to `%!task` and has no locks 05:35
I'd replace it with more boring `supply { whenever Promise.in(2) { … } }` and make process-buffer also have a supply 05:37
I'm not sure if it's a problem realistically too, it just scares me, that's all 05:38
timo i'm going back to bed, hopefully i can get rid of this headache 05:48
05:49 vasko4535586 joined
timo someone can decide if we should make a point release already for the moarvm fix for utf8 decoding hanging the process if there's an error 05:50
m: say Buf.allocate(10001).decode("utf8")
camelia ␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀…
timo ah that's not invalid of course
m: say Buf.allocate(0xf0 xx 10001).decode("utf8")
camelia Cannot resolve caller allocate(Buf:U: Seq:D); none of these signatures matches:
(Blob:U $:: Int:D $elements, *%_)
(Blob:U $:: Int:D $elements, Int:D \value, *%_)
(Blob:U $:: Int:D $elements, Mu:D $got, *%_)
(Blob:U $:: Int:D $e…
timo m: say Buf.new(0xf0 xx 10001).decode("utf8")
look how much trouble my brain is already having 05:51
camelia (timeout)
Voldenet but it's timeouting as it should
timo ^- this is the hang, it's pretty bad honestly and i'm pretty unhappy I just got that into moar without seeing the issue
camelia is timeouting it
if you run it locally the process will just wait on a condition variable forever 05:52
Voldenet yeah, of course
btw, I've tried and that supply problem I mentioned before wasn't related to github.com/rakudo/rakudo/blob/main...akumod#L20 06:32
m: start { sleep 5; say "timeout"; exit }; await Supply.new(Rakudo::Supply::BlockTappable.new(block => { &*ADD-WHENEVER(supply { die "foo" }, { QUIT { default { .say } } }) })); 06:35
camelia foo
in block at <tmp> line 1
in block <unit> at <tmp> line 1

timeout
Voldenet I've reproduced it with my own tappable too (with reordered tap/quit) and it didn't change anything 06:36
06:39 Sgeo left
simon_sibl Voldenet: "this line scares me" oops, but the read/write to %!task should be fine since only 1 whenever can run at a time right ? 06:40
I mean I checked many things to see what could cause the freeze, I thought maybe it's the %!task I send back in the todo-chan and would fill the Channel with corrupted tasks, I even checked if an empty %() would indeed return False if I do so %!task 06:43
I checked if maybe the sockets were accumulated and the OS would block my program from connecting to more peers, but thats not the problem as well (I added a timeout), same for the Cro http client, I added a timeout when reading the body, but it didnt help 06:44
and RAKUDO_SCHEDULER_DEBUG=1 didnt seem to show any thread/scheduling issue
(btw why in the Raku code, the directory is named core.c instead of core ?) 06:46
Voldenet yes but process-buffer can actually dispatch async work
at which point it stops being sync - promise just adds it to thread scheduler 06:47
the data loop runs process-buffer in a single-threaded way 06:49
and handle-piece is not async 06:50
so it's just that `request-work` can be ran in somewhat random way
either way, it'd be maybe better to have some sort of Lock::Async around it for sanity 06:57
librasteve weekly: gregdonald.com/pages/shipping-my-first-raku-app 07:02
notable6 librasteve, Noted! (weekly)
simon_sibl request-work is really the function I am not sure how to make it "clean", but even tho I have a bad feeling about it, I also have about the fetch-peers, which should be more straightforward. You would add a lock around %!task ? or somewhere inside request-work ? 07:22
07:22 abraxxa joined
Voldenet I've looked that request-work closely and it has ` $conn.write($req);` 07:26
despite how silly it sounds, I would make request-work a supply
07:28 hurufu left
Voldenet but hm, that sounds heavy-handed 07:28
maybe instead of doing request-work directly, I'd make a supplier that'd be able to do request-work 07:29
07:30 lichtkind joined 07:32 abraxxa1 joined 07:33 abraxxa left
Voldenet so that the `root work queue` for peers would dispatch it synchronously 07:47
07:48 dakkar joined
Voldenet and you could do from within `process-buffer` something like `$!work-requests.emit({ :pieces })` and from request-work `$!work-requests.emit({ :retry, attempt => ($request<attempt> // 0) + 1 })` 07:49
so the loop queue would also know the cause of running request-work 07:51
since it'd has hash with values
08:11 apogee_ntv joined
simon_sibl I dont follow everything but making request-work a supply makes sense, just I dont see where I would put it in the code and I would still need the global peer state to know if I need to pull from it ? 08:28
Voldenet nah, it'd be part of Peer still 08:30
on connection start, you'd have to create the supplier and on end (LAST/QUIT) you'd have to do `$!work-requests.done;`
m: my $work-requests = Supplier.new; start { sleep 1; $work-requests.emit({ :piece }); }; react { whenever Promise.in(5) { $work-requests.done; }; whenever $work-requests -> $r { $r.say; whenever Promise.in(.2) { $work-requests.emit({ attempt => ($r<attempt> // 0) + 1, :retry }); }}}; 08:31
camelia {piece => True}
{attempt => 1, retry => True}
{attempt => 2, retry => True}
{attempt => 3, retry => True}
{attempt => 4, retry => True}
{attempt => 5, retry => True}
{attempt => 6, retry => True}
{attempt => 7, retry => True}
{attempt …
Voldenet something like that
I think that global peer state is fine as long as you don't do it in different threads 08:32
if you do, it'd be best to have lock in Peer that'd protect writes and reads to %!task or other fields 08:34
and then separate method that meant to be thread-safe
09:01 abraxxa1 left 09:02 abraxxa joined 09:07 vasko4535586 left
simon_sibl alright, I just pushed to the main branch, not testing with what I understood from you 09:10
doesnt seem to be blocked anymore 09:11
now I will see if I can make the tracker fetch peers without a start{} 09:13
ok it stills block lol 09:16
let me share the backtrace from VM.own-up, hopefully someone can make sense of it: pastebin.com/PcizY0ZT 09:21
maybe I am blind, but it doesnt even show one of the file from my project ? 09:28
Voldenet I looked at the commit and that was what I meant 09:29
simon_sibl amazing, thank you
Voldenet maybe except `done`
it should be `$!work-bus.done`
it may not mean anything now, but if you plan to reconnect to peers, it will matter
because reconnecting would do `$!work-bus = Supplier.new;` 09:30
simon_sibl oh so I never done my peer, only the work-bus ?
Voldenet yeah, the outer supply would finish if all supplies are done 09:31
so, any cleanups and reconnects too
simon_sibl alright!, and for the tracker code, its not scary with the recursion call.. ? 09:32
I am not sure how that works but thats the only way I find to keep it without start{}
09:33 vasko4535586 joined
not to "keep" but to make all of this code without a single start{} I mean 09:33
Voldenet it looks nice 09:34
the only thing I' 09:35
I'd be worried about is backtrace growing with recursion if anything tracks it
m: react { whenever Promise.in(.5) { done }; sub fetch () { whenever Promise.in(.1) { say Backtrace.new; fetch() } }; fetch() }; 09:36
camelia Backtrace(30 frames)
Backtrace(30 frames)
Backtrace(30 frames)
Backtrace(30 frames)
Voldenet but it seems that backtrace is totally stable
09:38 vasko45355865 joined 09:39 vasko4535586 left, vasko45355865 is now known as vasko4535586
simon_sibl so its not the recursion either I guess.. 🤔 09:47
lmao kamelia think :cameliathink: 09:48
09:48 vasko45355861 joined 09:50 vasko4535586 left
Voldenet I've looked at those backtraces, nothing looks like it's hanging 09:50
it looks like… it's simply waiting for events
simon_sibl hmmm thats weird cause it shows peers are connected, but the fetch-peers stop being triggered (the number of peers dont change) and no piece arrive 09:51
would that be a logic bug on how I handle pieces then ? idk, it always shows at least 37 peers, should be enough to get all the debian iso pieces.. 09:52
Voldenet hm, but I see that fetch-peers is running in timed loop though 09:53
that shouldn't hang 09:54
09:54 vasko45355861 left
Voldenet unless `Cro::HTTP::Client.get` hangs 09:54
simon_sibl I just could download the whole iso without hanging, it doesnt seem to hang often if I dont mess with the fetch-peers, to test I try to change the interval to 20 or 30 seconds and then it hangs faster, but since I am not sure where it comes from, I am "afraid" it can still happen in longer torrent even without messing with the interval 09:56
lizmat fwiw, I love Cro server side, client side not so much... I usually just do "run <curl ...>, :out"
09:56 wayland76 joined
simon_sibl >< 09:56
09:56 wayland left 09:58 vasko45355861 joined
Voldenet well, not hangs, but maybe awaits eternally 09:58
simon_sibl for which part could that happen ? 09:59
the fetch-peers ?
Voldenet yeah, if you don't see fetch-peers running then that's the only explanation
simon_sibl but even when I tried using anyof with timeout and all, somehow it still makes it hang 10:00
the weird part was, I added timeout for the body, and as a good debugging strategy printed "Body OK" if the body-blob won over the timeout, but after the print it still hang, so between getting the body and emit the IPs 10:01
Voldenet ah, right, what if you get http error
simon_sibl now maybe thats my bad because of its possible the tracker sends ipv6 (not sure actually, but possible) but then I should get a traceback and exception no ?
in the current state of the code, if I get an http error, I should get a traceback right ? 10:03
Voldenet yeah, you should get `network unreachable`
simon_sibl and I dont get any traceback when it hangs :cameliathink:
if you have the time, if you change the fetch peer from whenever Promise.in(%reply<interval> // 1800) { fetch() } to whenever Promise.in(20 // %reply<interval> // 1800) { fetch() } it should also hang 10:04
after some time, and wont show any traceback
10:08 vasko45355861 left
Voldenet I've tried and it does download the debian-12.6.0-amd64-netinst.iso for me, checksum is fine too 10:12
10:16 camelia left 10:18 nine left 10:21 camelia joined 10:23 nine joined
simon_sibl So no freeze even when messing with the interval ? Interesting 🫠 then really don’t know what’s going on my machine when messing with that interval 10:25
Voldenet ah, I've tried and it's that 10:27
very soon after getting a list of peers (and emitting it) it hangs, but it's totally not easy to reproduce 10:38
sometimes it just works 10:41
10:50 vasko45355861 joined
simon_sibl Oh omg okok so it’s not just me 10:52
Any idea why would that happen ? Is it my Set code that is wrong ? 10:53
wayland76 There was a bug in Set recently, but it's fixed now. Can't remember whether it was fixed in the May or June release. 11:01
simon_sibl Would you have any link or any info about that bug ? I’m interested 🙏 I hope that bug fix is about what the same bug 11:07
11:09 guifa_ left
> Properly support coercive types on parameterized Set(Hash) [ab6efcab] 11:15
From Rakudo compiler, Release #192 (2026.04) 11:16
11:19 guifa_ joined
Voldenet: which rakudo version are you using ? 11:23
I use Welcome to Rakudo™ Star v2026.05, so I guess the bug must be different if it is one 11:26
Voldenet > 2026.04-23-gd4cd2babd 11:50
Though it's time to upgrade :> 11:51
12:01 abraxxa1 joined 12:03 abraxxa left
Voldenet I think this problem is actually some sort of deadlock 12:31
simon_sibl what could it be related to ? the pieces are released into the channel and a peer can at most take one 12:33
so there should always be pieces to take
even if there is no piece, it will give up after a while and try after few seconds 12:34
I dont see how other part of the code could deadlock
Voldenet I've added `whenever Supply.interval(5) { say "runtime {$_*5}s"; }` to Downloader and it just stopped responding after a while 12:42
bah, the process never dies, add `say "getting task for {$!address}";` to `whenever $!work-bus.Supply {` and see how talkative it is 13:08
second surprise, $conn.write actually returns a promise that can fail :p 13:19
13:23 apogee_ntv left
simon_sibl yeaaah I also tried making a Supply that should run all the time every few seconds but it stopped printing during the freeze 13:31
but if anything fails, since there is no start{} should abort and show a stacktrace right ? 13:32
you got an exception because of a $conn.write ?
Voldenet nope, but it's async - I don't know what happens when you do $conn.write before previous one ends 13:33
ultimately though, the problem is with `$!todo-chan.poll` 13:34
it is quite a busy loop 13:35
simon_sibl I did this approach because thats what I could do in Go, maybe there is a better way to handle this in Raku, a more "idiomatic" way ? 13:37
Voldenet in go, you do all this on event scheduler
so goroutines with channels are totally not using `react whenever`
but instead `start { react whenever $todo-chan { } }` etc. 13:38
in raku .poll is blocking, in golang nothing is actually blocking
simon_sibl I thought .poll wasnt blocking 13:39
> Receives and removes an item from the Channel. If no item is present, returns Nil instead of waiting
Voldenet ah, nevermind 13:41
I confused .poll with .receive
simon_sibl you are very helpful and I really dont want to abuse your help, can I ask if you can explain in a more simple way what you meant is the difference with the Go channel way ?
librasteve fwiw every channel in Occam blocks on oth input and output - while it can be painful to code, it is like strict typing and helps prevent the async bugs that you guys are wrestling with 13:42
Voldenet in go `w := <-todo_chan` actually does scheduler magic that suspends the goroutine 13:44
in a way that feels blocking, but is a lot faster
simon_sibl If the implementation or the difference makes it slower in Raku, shouldn’t it just then be slower instead of suddenly freeze ? 13:45
Voldenet the thing is that it doesn't freeze 13:46
simon_sibl It waits forever for..something ? 13:47
And doesn’t execute the other whenever like the Supply.interval
ugexe librasteve: i dont think that saying "this non-async thing avoids the async issues you all are seeing" is a very convincing argument :P 13:49
Voldenet near `whenever $!work-bus.Supply { next if $!choked; ` add `say "finding work for {$!address}";`
it keeps crunching numbers :> 13:50
actually, as it works now, I think Peers should be fully async 13:52
aruniecrisps Is gdonald in here?
Wanted to ask about ActiveRecord
Voldenet multiple peers competing for pieces in separate places than the main event loop would probably work better 13:53
in single-threaded scenario, it'd be better to, after getting new peers or new pieces dispatch the work to work scheduler 13:58
that would, given some work, find non-busy peer able to do it
simon_sibl I am not sure to grasp what’s wrong with the current implementation, all the peers competing for a piece are non busy peer 14:00
Aren’t the peers already all async, anything in the code can behave in any order and still be correct 14:01
Voldenet I'm not sure either, all I see after a while is that peers keep looking for work aggressively and no other Supply.interval gets executed 14:02
librasteve Occam is async (well, was, since it has long disappeared without much trace) - it's a full blown Hoare CSP with a built in microkernel (like Go) ... anyway one day I will write an Occam slang in Raku and amaze the world 14:03
simon_sibl By Occam you mean Ocaml ? Or it’s something else ? 14:04
librasteve nope, Occam
simon_sibl Voldenet: if all of those were trying to get a pieces and didn’t succeed because the peer doesn’t have it (very unlikely) 14:05
librasteve en.wikipedia.org/wiki/Occam_(progr..._language)
14:05 abraxxa1 left
Voldenet yes and in fact I don't get what the impact could tracker fetch have on that as well 14:08
14:09 abraxxa joined
Voldenet after all it only adds new peers to the mix 14:09
haha wait a moment 14:10
downloader has `whenever $done-chan.Supply -> %chunk { $todo-chan.send: %( index => %chunk<index>, length => %chunk<blob>.bytes ); }` 14:11
all _idle_ peers have `while my $w = $!todo-chan.poll { $!todo-chan.send($_) for @requeue; ` 14:12
so after a while, idle peers play ping pong with downloader it seems
which keeps the loop busy
ah, it's a separate queue, nevermind 14:13
14:13 abraxxa left
Voldenet it's time to stop coding itseems 14:14
lizmat raku 3 14:31
oops ww
simon_sibl "time to stop coding" xD 15:10
this async code bug is mind breaking really
lizmat async bugs always are :-( 15:13
ugexe just do what i do and add "say "FUCK1", "say SHIT234" on every other line in the rakudo core nqp and moarvm so you know exactly what is happening 15:14
lizmat
.oO( that sounds *very familiar :-)
and just hope that the debug messages won't actually hide any async issues
ugexe that just means you need say FUCK23490 debugging at least one level lower in addition to the higher level say SHIT2349 debugging 15:16
simon_sibl ;-; 15:31
15:50 human-blip left 15:52 human-blip joined
lizmat: .o0(<text>) is supposed to show big eyes like surprises or it’s supposed to be like a comics bubble to show in mind thoughts ? 16:21
lizmat mind thoughts 16:22
16:24 rmv joined
simon_sibl I see, I’ll steal that, I forgot who sent this but I also like the o7 16:26
16:29 rmv left 16:31 dakkar left 16:35 gabiruh joined 17:11 rmv joined
timo i think the freezes of rbt might be what I just fixed in moarvm 17:17
that's how i found the bug after all
17:21 gabiruh left 17:22 gabiruh joined
lizmat timo: so it's good to be merged ? 17:28
timo it'd be good if someone reviewed it to make sure it makes sense actually
it'd also be possible to just revert the optimization completely 17:29
18:09 rmv left 18:48 rmv joined
aruniecrisps @lizmat I know I'm the latest release that macros have been disabled, is there an idea of what macros would look like in Raku if they were implemented? 18:56
19:01 abraxxa joined 19:05 librasteve_ left 19:16 rmv left 19:23 rmv joined
tadzik perl6advent.wordpress.com/2012/12/...23-macros/ is dated but it may give you an idea :) 19:37
20:28 wayland76 left, wayland76 joined, abraxxa left 21:20 hurufu joined 21:49 hurufu left 21:58 wayland76 left 21:59 wayland76 joined 22:09 rmv left 22:11 rmv joined, rmv left, rmv joined 22:14 wayland76 left, wayland76 joined 22:18 Sgeo joined 22:19 wayland76 left, wayland76 joined