Re: Terminating multiple processes – SOLVED

2018-02-05 Thread Russel Winder via Digitalmars-d-learn
On Fri, 2018-02-02 at 20:14 +, David Nadlinger wrote:
> 
[…]
> That sounds entirely sensible. Your original question was whether it
> was 
> possible to terminate threads blocked in a syscall, though. Signals 
> allow you to do that on POSIX for many "slow" syscalls, by making it 
> return EINTR. You would check whatever channel/atomic flag/…
> mechanism 
> you use to signal termination before continuing to block by
> reissuing 
> the syscall.
> 
> I haven't tested how `read` behaves for inotify myself, but
> inotify(7) 
> suggests that it indeed handles signals this way.
[…]

After some discussions, Dmitry acted very quickly and added a timeout
read to the blocking read in dinotify.

This solves my problem "at a stroke" as I can now block waiting for a
specific time on inotify and then check the input channel for a time
and repeat. Not really busy wait just a sequence of blocking reads with
timeouts. The important thing is that With very little latency, the
thread is checking two things.

DInotify 0.3.0 will likely appear soon in Dub. It would be good to get
it packaged for Debian. I will take up an invitation to submit a ready
made package for the Debian D packaging team.


-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk


signature.asc
Description: This is a digitally signed message part


Re: Terminating multiple processes

2018-02-02 Thread Russel Winder via Digitalmars-d-learn
On Thu, 2018-02-01 at 20:13 +, Arek via Digitalmars-d-learn wrote:
> 
[…]
> DInitify doesn't cover full capabilities of the inotify API.
> Especially it doesn't utilize newer inotify_init1 syscall and 
> doesn't expose 'select' interface.
> This C++ wrapper may be interesting for you: 
> https://github.com/erikzenker/inotify-cpp
> But I haven't used it.

Hummm… sounds like I need to look to create a pull request to get to
dinotify 0.2.3 or even 0.3.0.

> > > 
[…]
> You may be right. But interrupting the thread is very low level 
> mechanism.
> Eg in Java, it is incorporated into Thread class: thread has 
> method 'interrupt()' which
> sets the flag, and there is property 'isInterrupted()'. Usually 
> your thread code have something like  
> while(!Thread.currentThread().isInterrupted()) { /* do 
> something*/ }
> I would use similar pattern.

I do want to avoid such low-level things, they may be required for
building libraries, but they seem totally the wrong level of concept
for an application.

I am definitely headed to the (select|poll|epoll) on the inotify file
descriptor to get the timeout, and then either read or check the input
channel for termination or an atomic Boolean state variable. Channels
seem most likely since parent threads send a terminating token.


-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk


signature.asc
Description: This is a digitally signed message part


Re: Terminating multiple processes

2018-02-02 Thread Russel Winder via Digitalmars-d-learn
On Fri, 2018-02-02 at 01:09 +, David Nadlinger via Digitalmars-d-
learn wrote:
> On Thursday, 1 February 2018 at 11:42:32 UTC, Russel Winder wrote:
> > The problem is actually a thread blocked in an inotify blocking 
> > read. As both Steven and yourself have pointed out I am going 
> > to have to use a timeout to check the state of the application.
> 
> There are better solutions (select/...), But couldn't you in 
> theory just send a custom signal to the thread (which you 
> ignore), and then check for the exit flag after the syscall 
> returned EINTR?

I think I am going to go the (select|poll|epoll) on the file descriptor
with a timeout and then the read if that is appropriate or check the
input channel for the terminate token if that is appropriate.

The question whether to do this in my code or create a "read with
timeout" in dinotify

> The DInotify wrapper might of course have the retry loop 
> hardcoded; I didn't check.

Dinotify adds the tree monitoring as an extra over the inotify API but
U do not see any timeout related things.

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk


signature.asc
Description: This is a digitally signed message part


Re: Terminating multiple processes

2018-02-01 Thread David Nadlinger via Digitalmars-d-learn

On Thursday, 1 February 2018 at 11:42:32 UTC, Russel Winder wrote:
The problem is actually a thread blocked in an inotify blocking 
read. As both Steven and yourself have pointed out I am going 
to have to use a timeout to check the state of the application.


There are better solutions (select/...), But couldn't you in 
theory just send a custom signal to the thread (which you 
ignore), and then check for the exit flag after the syscall 
returned EINTR?


The DInotify wrapper might of course have the retry loop 
hardcoded; I didn't check.


 —David


Re: Terminating multiple processes

2018-02-01 Thread Arek via Digitalmars-d-learn

On Thursday, 1 February 2018 at 12:30:24 UTC, Russel Winder wrote:
On Thu, 2018-02-01 at 12:15 +, Arek via Digitalmars-d-learn 
wrote:



[…]
Try to use inotify in non-blocking mode (an example here: 
https://gist.github.com/pkrnjevic/6016356) with select or 
epoll and timeouts.


Isn't there a C++ binding for the C API?

I am using DInotify which is a D binding. I will be checking 
soon but I am assuming there is a timeout version so I can loop 
to check the application state.



DInitify doesn't cover full capabilities of the inotify API.
Especially it doesn't utilize newer inotify_init1 syscall and 
doesn't expose 'select' interface.
This C++ wrapper may be interesting for you: 
https://github.com/erikzenker/inotify-cpp

But I haven't used it.



I would use shared memory here (eg. atomic bool) because any 
communication channel introduces possibility of further 
blocking problems.


A priori I am not convinced. I have used a state variable in 
C++ and Python code where there is no channel system, but in 
Go, Groovy/GPars, using channels is always preferable. Given 
the channel has a "read if there is something to read" there 
can't be a blocking problem – if the channel system is a good 
one.
You may be right. But interrupting the thread is very low level 
mechanism.
Eg in Java, it is incorporated into Thread class: thread has 
method 'interrupt()' which
sets the flag, and there is property 'isInterrupted()'. Usually 
your thread code have something like  
while(!Thread.currentThread().isInterrupted()) { /* do 
something*/ }

I would use similar pattern.


Arek





Re: Terminating multiple processes

2018-02-01 Thread Russel Winder via Digitalmars-d-learn
On Thu, 2018-02-01 at 12:15 +, Arek via Digitalmars-d-learn wrote:
> 
[…]
> Try to use inotify in non-blocking mode (an example here: 
> https://gist.github.com/pkrnjevic/6016356) with select or epoll 
> and timeouts.

Isn't there a C++ binding for the C API?

I am using DInotify which is a D binding. I will be checking soon but I
am assuming there is a timeout version so I can loop to check the
application state.

> > 
> > I guess there is a choice here between shared memory to set the 
> > termination flag, or using an input channel and sending the 
> > termination message. I think the latter may be preferable, and 
> > certainly more consistent with how the other threads terminate.
> > 
> 
> I would use shared memory here (eg. atomic bool) because any 
> communication channel introduces possibility of further blocking 
> problems.

A priori I am not convinced. I have used a state variable in C++ and
Python code where there is no channel system, but in Go, Groovy/GPars,
using channels is always preferable. Given the channel has a "read if
there is something to read" there can't be a blocking problem – if the
channel system is a good one.

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk


signature.asc
Description: This is a digitally signed message part


Re: Terminating multiple processes

2018-02-01 Thread Arek via Digitalmars-d-learn

On Thursday, 1 February 2018 at 11:42:32 UTC, Russel Winder wrote:
On Wed, 2018-01-31 at 22:15 +, Arek via Digitalmars-d-learn 
wrote:



[…]

The problem is actually a thread blocked in an inotify blocking 
read. As both Steven and yourself have pointed out I am going 
to have to use a timeout to check the state of the application.


Try to use inotify in non-blocking mode (an example here: 
https://gist.github.com/pkrnjevic/6016356) with select or epoll 
and timeouts.




I guess there is a choice here between shared memory to set the 
termination flag, or using an input channel and sending the 
termination message. I think the latter may be preferable, and 
certainly more consistent with how the other threads terminate.


I would use shared memory here (eg. atomic bool) because any 
communication channel introduces possibility of further blocking 
problems.


Arek





Re: Terminating multiple processes

2018-02-01 Thread Russel Winder via Digitalmars-d-learn
On Wed, 2018-01-31 at 22:15 +, Arek via Digitalmars-d-learn wrote:
> 
[…]
> Assuming your're talking about threads: there's no secure method 
> of forcing the thread to stop. Threads share the state (eg. can 
> hold the locks) and killing them is always risky.

I am indeed talking threads not OS processes. I just like working with
(processes|tasks) submitted to a thread pool, but this can lead to
jargon use problems.

> If your threads are blocked reading the socket, you probably can 
> close these sockets and exit after the read error.

The problem is actually a thread blocked in an inotify blocking read.
As both Steven and yourself have pointed out I am going to have to use
a timeout to check the state of the application. 

> Another way is to use atomic flag indicating that thread needs to 
> be interrupted.
> After any blocking operation, the thread have to check this flag 
> and finish the job.
> It's good to use timeouts (eg socket timeout) in such scenario 
> (if possible).

I guess there is a choice here between shared memory to set the
termination flag, or using an input channel and sending the termination
message. I think the latter may be preferable, and certainly more
consistent with how the other threads terminate.

Thanks to you and Steven for confirming what I had been fearing, but
wondered if there was an easier (albeit less theoretically sound) one.
 
-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk


signature.asc
Description: This is a digitally signed message part


Re: Terminating multiple processes

2018-02-01 Thread Russel Winder via Digitalmars-d-learn
On Wed, 2018-01-31 at 13:26 -0500, Steven Schveighoffer via
Digitalmars-d-learn wrote:
> 
[…]
> You talking about processes or threads? `receive` I believe is an 
> inter-thread channel, no?

These are threads with no shared memory, just message passing via
channels. I think of them as processes, but not OS processes. My poor
choose of names, I should just have said threads.

> Terminating processes is generally done via signals or in the case
> of 
> windows, calling the right system call.

Indeed. usually SIGHUP or SIGTERM, but never SIGKILL.

> Threads are another story. Typically, you need to have the thread
> check 
> periodically for a termination event. There's no "nice" way to do it
> out 
> of band.

This is what I was fearing. Of course from a theoretical standpoint it
is the right way to do things.

> In my experience, the best way to do it is to never block, but use
> some 
> sort of "wait on input" for any would-be-blocking operation. You can
> use 
> a large timeout, like 1 second, if immediate termination isn't
> important.

The thread in question is usually blocked in an inotify wait state
having no input channel. It seems I will have to manufacture a select.

I think this is what is missing in D, or at least my knowledge of it.
In Go, I can set up a select between channels and block, no need for a
timeout, an input on either channel causes a wakeup. The code then has
to work out which channel caused the wakeup. On the other hand DInotify
doesn't provide a channel style blocking wait, so select isn't an
option.

> If you are using Fibers, and all your i/o is done using some event-
> based 
> system (e.g. vibe.d), then things can be easier.

I am not sure I want to get into single-threaded event queues, but
maybe I should. I like the dataflow approach, it is simpler for me to
reason about.

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk


signature.asc
Description: This is a digitally signed message part


Re: Terminating multiple processes

2018-01-31 Thread Arek via Digitalmars-d-learn
On Wednesday, 31 January 2018 at 17:44:37 UTC, Russel Winder 
wrote:
So, I have an application which has a sort of nano-services 
architecture, basically it is a set of communicating processes. 
Terminating those processes blocked on an input channel is 
quite easy, send a terminate message on the input channel. But 
what about a process that has no input channel, one that is 
blocked on OS events?


Is there a way of forcibly, but nicely, terminating a spawned 
process that never executes `receive()`?


Assuming your're talking about threads: there's no secure method 
of forcing the thread to stop. Threads share the state (eg. can 
hold the locks) and killing them is always risky.


If your threads are blocked reading the socket, you probably can 
close these sockets and exit after the read error.


Another way is to use atomic flag indicating that thread needs to 
be interrupted.
After any blocking operation, the thread have to check this flag 
and finish the job.
It's good to use timeouts (eg socket timeout) in such scenario 
(if possible).


Arek


Re: Terminating multiple processes

2018-01-31 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/31/18 12:44 PM, Russel Winder wrote:

So, I have an application which has a sort of nano-services
architecture, basically it is a set of communicating processes.
Terminating those processes blocked on an input channel is quite easy,
send a terminate message on the input channel. But what about a process
that has no input channel, one that is blocked on OS events?

Is there a way of forcibly, but nicely, terminating a spawned process
that never executes `receive()`?



You talking about processes or threads? `receive` I believe is an 
inter-thread channel, no?


Terminating processes is generally done via signals or in the case of 
windows, calling the right system call.


Threads are another story. Typically, you need to have the thread check 
periodically for a termination event. There's no "nice" way to do it out 
of band.


In my experience, the best way to do it is to never block, but use some 
sort of "wait on input" for any would-be-blocking operation. You can use 
a large timeout, like 1 second, if immediate termination isn't important.


If you are using Fibers, and all your i/o is done using some event-based 
system (e.g. vibe.d), then things can be easier.


-Steve


Terminating multiple processes

2018-01-31 Thread Russel Winder via Digitalmars-d-learn
So, I have an application which has a sort of nano-services
architecture, basically it is a set of communicating processes.
Terminating those processes blocked on an input channel is quite easy,
send a terminate message on the input channel. But what about a process
that has no input channel, one that is blocked on OS events?

Is there a way of forcibly, but nicely, terminating a spawned process
that never executes `receive()`?

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk


signature.asc
Description: This is a digitally signed message part