I really like how Rolando described the sequence of operations
a replication performs. However, I think it would be more clear
if we add another component - client.

With client the sequence of operations for asynchronous replication
could be the following:

1. Client sends to the master the SQL query (for example, insert)
   using transactions

2. Master executes the transaction. In case of success the record 
   is stored on the disk, but the transaction is not committed yet.

3. Master records the insertion event in the master binary log
   If the master could not store it in the binary log, the
   transaction rolled back.

4. Client receives response from the master (success or rollback).

5. In case of transaction success, the dump thread on the master
   reads the event from the binary log and send it to the slave 
   I/O thread.

6. Slave I/O thread receives the event and writes it to the end of
   the relay log file.

7. Once the event got into relay log, the slave SQL thread executes   
   the event to apply the changes to the database on the slave.

In this scenario master does not care about the slave and client
only knows that something is wrong on the slave by manually executing 
"SHOW SLAVE STATUS" command.

n case of a semi-synchronous replication the sequence of operations could 
be the following:

1. Client sends to the master the SQL query (for example, insert)
   using transactions.

2. Master executes the transaction. In case of success the record 
   is stored on the disk, but the transaction is not committed.

3. Master records the insertion event in the master binary log
   If the master could not store it in the binary log, the
   transaction rolled back and client receives the response only
   in the case of rollback.

4. Due to the success of the transaction on the master, the dump 
   thread on the master reads the event from the binary log and 
   send it to the slave I/O thread.

5. Slave I/O thread receives the event and writes it to the end of
   the relay log file.

6. Slave Acknowledges Master of the recording the event in the relay
   log file.

7. Master commits the insertion transaction.

8. Client receives the response from the master (success).

9. Once the event got into relay log, the slave SQL thread executes   
   the event. Master and client don't know whether the execution
   was successful or not.

The semi-synchronous replication solved one important case
when slave or network died and master continued to proceed. 
Then master dies and you want to restart the old slave as new 
master just because you fixed that node. 

So you started that node as new master, you fixed the old master
and now you want to use it as slave. That node still has the data,
but if the new slave starts from the position where the new master
started there will be duplicate records.

If waiting period is infinite, master binary log position always 
will be in sync with the slave relay log position assuming that
all queries on the slave were successful. How realistic this 
assumption?

I think it is very realistic. One of the most common case of the 
slave query failure is "duplicate record". Where the duplicate record
came to the slave if master did not have it? It came from wrong position
given to the slave to start to replicate. The starting replication
position included the record that was already replicated. In case of
semi-synchronous replication this situation will not happened.

Jacob Nikom