

OVERALL STATES, defining interaction with innd:

  F refers to the main feed file as written by innd
  D refers to the flushing file <feedfile>_flushing

								START
								  |
     ,-->--.                                                 check F, D
     |     |                                                      |
     |     |                                                      |
     |     |  <----------------<---------------------------------'|
     |     |                                       F exists       |
     |     |                                       D ENOENT       |
     |     |  duct opens F                                        |
     |     V                            	                  |
     |  Normal                                                    |
     |   F: innd writing, duct reading                            |
     |   D: ENOENT                                                |
     |     |                                                      |
     |     |  duct decides time to flush                          |
     |     |  duct makes hardlink                                 |
     |     |                                                      |
     |     V                            <------------------------'|
     |  Hardlinked                                  F==D          |
     |   F == D: innd writing, duct reading         both exist    |
     ^     |                                                      |
     |     |  duct unlinks F                                   	  |
     |     |                        <-----------<-------------<--'|
     |     |                           open D         F ENOENT    |
     |     |                           if exists                  |
     |     |                                                      |
     |     V                        <---------------------.       |
     |  Moved                                             |       |
     |   F: ENOENT                                        |       |
     |   D: innd writing, duct reading; or ENOENT         |       |
     |     |                                              |   	  |
     |     |  duct requests flush of feed                 |   	  |
     |     |   (others can too, harmlessly)               |   	  |
     |     V  			      	   	   	  |   	  |
     |  Flushing                              	   	  |   	  |
     |   F: ENOENT                             	   	  |   	  |
     |   D: innd flushing, duct; or ENOENT        	  |   	  |
     |     |   	      		       	       	  	  |   	  |
     |     |   inndcomm flush fails    	       	  	  |   	  |
     |     |`-------------------------->------------------'   	  |
     |     |   	       			  	 	      	  |
     |     |   inndcomm reports no such site                   	  |
     |     |`---------------------------------------------------- | -.
     |     |	      			  	    	      	  |  |
     |     |  innd finishes writing D, creates F    	      	  |  |
     |     |  inndcomm reports flush successful	    	      	  |  |
     |     |                                                   	  |  |
     |     V                                     	       	  |  |
     |  Separated                                <----------------'  |
     |   F: innd writing                            F!=D             /
     |   D: duct reading; or ENOENT                  both exist     /
     |     |                                                       /
     |     |  duct gets to the end of D                           /
     |     |  duct opens F too                                 	 /
     |     V                                                    /
     |  Finishing                                              /
     |   F: innd writing, duct reading                        |
     |   D: duct finishing                                    V
     |     |                                           	Dropping
     |     |  duct finishes processing D       	 	 F: ENOENT
     |     V  duct unlinks D                   	       	 D: duct reading
     |     |                            		      |
     `--<--'                            		      | duct finishes
							      |  processing D
							      | duct unlinks D
							      | duct exits
							      V
							Dropped
							 F: ENOENT
							 D: ENOENT
							 duct not running

   "duct reading" means innduct is reading the file but also
   overwriting processed tokens.



We implement this as follows:

	    .=======.
	    ||START||
	    `======='
		|
		| open F
		|
		|    F ENOENT
		|`---------------------------------------------------.
      F OPEN OK |                                                    |
		|`---------------- - - -                             |
       D ENOENT |       D EXISTS   see OVERALL STATES diagram        |
		|                  for full startup logic            |
     ,--------->|                                                    |
     |          V                                                    |
     |     ============                                       try to |
     |      NORMAL                                            open D |
     |     [Normal]                                                  |
     |      main F tail                                              |
     |     ============		    	      		      	     V
     |          |      		    	      		      	     |
     |          | F IS SO BIG WE SHOULD FLUSH, OR TIMEOUT     	     |
     ^          | hardlink F to D   	      		      	     |
     |     [Hardlinked]		    	      		             |
     |          | unlink F	    	       	       	             |
     |          | our handle onto F is now onto D	     	     |
     |     [Moved]     		    	      			     |
     |          |      		    	      			     |
     |          |<-------------------<---------------------<---------+
     |          |                                                    |
     |          | spawn inndcomm flush                               |
     |          V                                                    |
     |     ==================                                        |
     |      FLUSHING[-ABSENT]                                        |
     |     [Flushing]                                                |
     |     main D tail/none                                          |
     |     ==================                                        |
     |          |                                                    |
     |          |   INNDCOMM FLUSH FAILS                             ^
     |          |`----------------------->----------.                |
     |          |                                   |                |
     |          |   NO SUCH SITE                    V                |
     ^          |`--------------->----.         ==================== |
     |          |                      \        FLUSHFAILED[-ABSENT] |
     |          |                       \         [Moved]            |
     |          | FLUSH OK               \       main D tail/none    |
     |          | open F                  \     ==================== |
     |          |                          \        |                |
     |          |                           \       | TIME TO RETRY  |
     |          |`------->----.     ,---<---'\      `----------------'
     |          |    D NONE   |     | D NONE  `----.
     |          V             |     |              V
     |     =============      V     V          	  ============
     |      SEPARATED-1       |     |              DROPPING-1
     |      flsh->rd!=0       |     |              flsh->rd!=0
     |     [Separated]        |     |             [Dropping]
     |      main F idle       |     |              main none
     |      flsh D tail       |     |              flsh D tail
     |     =============      |     |             ============
     |          |             |     | install       |
     ^          | EOF ON D    |     |  defer        | EOF ON D
     |          V             |     |               V
     |     ===============    |     |             ===============
     |      SEPARATED-2       |     |              DROPPING-2
     |      flsh->rd==0       |     V              flsh->rd==0
     |     [Finishing]        |     |             [Dropping]
     |      main F tail	      |     `.             main none
     |      flsh D closed     |       `.           flsh D closed
     |     ===============    V	        `.        ===============
     |          |	       	          `.          |
     |          | ALL D PROCESSED           `.        | ALL D PROCESSED
     |          V install defer as backlog    `.      | install defer
     ^          | close D                       `.    | close D
     |          | unlink D                        `.  | unlink D
     |          |                                  |  |
     |          |                                  V  V
     `----------'                               ==============
						 DROPPED
						[Dropped]
						 main none
						 flsh none
						 some backlog
						==============
						      |
						      | ALL BACKLOG DONE
						      |
						      | unlink lock
						      | exit
						      V
						  ==========
						   (ESRCH)
						  [Droppped]
						  ==========


rune for printing diagrams:
  a2ps -R -B -ops README.states



#  part of innduct
#  tailing reliable realtime streaming feeder for inn
#
#  Copyright Ian Jackson <ijackson@chiark.greenend.org.uk>
#  and contributors; see LICENCE.txt.
#  SPDX-License-Identifier: GPL-3.0-or-later
