it also seems to work ok, although without calling the get device information (which isn't needed by my code but does no harm).

Code:

Job: 1 Get device information started
DeviceJob: 1 Get device information done, calling callback
DeviceJob: 1 Get device information callback returned
Job: 2 Get list of books on device started
Job: 1 Get device information finished
DeviceJob: 2 Get list of books on device done, calling callback
DeviceJob: 2 Get list of books on device callback returned
Job: 3 Upload 5 books to device:Life, the Universe and Everything, So Long, and Thanks For All the Fish, Mostly Harmless, The Hitchhiker’s_Guide_to the Galaxy, The_Restaurant_at the End of the Universe started
Job: 2 Get list of books on device finished
DeviceJob: 3 Upload 5 books to device:Life, the Universe and Everything, So Long, and Thanks For All the Fish, Mostly Harmless, The Hitchhiker’s_Guide_to the Galaxy, The_Restaurant_at the End of the Universe done, calling callback
DeviceJob: 3 Upload 5 books to device:Life, the Universe and Everything, So Long, and Thanks For All the Fish, Mostly Harmless, The Hitchhiker’s_Guide_to the Galaxy, The_Restaurant_at the End of the Universe callback returned
Job: 6 Send metadata to device started
Job: 3 Upload 5 books to device:Life, the Universe and Everything, So Long, and Thanks For All the Fish, Mostly Harmless, The Hitchhiker’s_Guide_to the Galaxy, The_Restaurant_at the End of the Universe finished
DeviceJob: 6 Send metadata to device done, calling callback
DeviceJob: 6 Send metadata to device callback returned
Job: 4 Create Kindle Collections started
Job: 6 Send metadata to device finished
DeviceJob: 4 Create Kindle Collections done, calling callback
DeviceJob: 4 Create Kindle Collections callback returned
Job: 5 Get list of books on device started
Job: 4 Create Kindle Collections finished
DeviceJob: 5 Get list of books on device done, calling callback
DeviceJob: 5 Get list of books on device callback returned
Job: 5 Get list of books on device finished

If I change the last FunctionDispatcher to self.Dispatcher it doesn't seem to affect things.

All of these calls are made in the main routine just after starting the collections job and not in the complete function. As things seem to work ok with the plugin as is (even with an extra call to get device info), I'll leave everything alone for now. Unless you recommend changing the placement or the function calls themselves.

The order is what I would expect to see. Using job sequencing forces job 6 (finishing the sync_metadata) to run ahead of job 4 (kindle collections), so that the device and the gui views are in a good state before collections are made. As it was before, kindle collections would run before the sync_metadata see stale data on the device and on the gui, and the sync_metadata job it schedules would fight with one that hadn't run yet.

You need to use FunctionDispatcher if either you want to finish some work before the next job starts or if you want to schedule a following job step. Neither of these seem to be true for you, which is why it doesn't matter.