code: func (s *SeesawSync) Poll(id SyncSessionID, sn *SyncNotes) error {
  	if sn == nil {
  		return errors.New("sync notes is nil")
  	}
  
  	s.sync.sessionLock.RLock()
  	session, ok := s.sync.sessions[id]
  	s.sync.sessionLock.RUnlock()
  	if !ok {
  		return errors.New("no session with ID %d")
  	}
  
  	// Reset expiry time and check for desynchronisation.
  	session.Lock()
  	session.expiryTime = time.Now().Add(sessionDeadtime)
  	if session.desync {
  		// TODO(jsing): Discard pending notes?
  		sn.Notes = append(sn.Notes, SyncNote{Type: SNTDesync})
  		session.desync = false
  		session.Unlock()
  		return nil
  	}
  	session.Unlock()
  
  	// Block until a notification becomes available or our poll expires.
  	select {
  	case note := <-session.notes:
  		sn.Notes = append(sn.Notes, *note)
  	case <-time.After(syncPollTimeout):
  		return errors.New("poll timeout")
  	}
  pollLoop:
  	for i := 0; i < syncPollMsgLimit; i++ {
  		select {
  		case note := <-session.notes:
  			sn.Notes = append(sn.Notes, *note)
  		default:
  			break pollLoop
  		}
  	}
  
  	log.V(1).Infof("Sync server poll returning %d notifications", len(sn.Notes))
  
  	return nil
  }
docs: // Poll returns one or more synchronisation notifications to the caller,
  // blocking until at least one notification becomes available or the poll
  // timeout is reached.