'Check if a sync session is complete.
:param array: the array serial number
:param source_device_id: source device id
:param target_device_id: target device id
:param snap_name: snapshot name
:param extra_specs: extra specifications
:returns: bool'

def is_sync_complete(self, array, source_device_id, target_device_id, snap_name, extra_specs):

    def _wait_for_sync():
        'Called    at    an    interval    until    the    synchronization    is    finished.\n\n                                                :raises:    loopingcall.LoopingCallDone\n                                                :raises:    VolumeBackendAPIException\n                                                '
        retries = kwargs['retries']
        try:
            kwargs['retries'] = (retries + 1)
            if (not kwargs['wait_for_sync_called']):
                if self._is_sync_complete(array, source_device_id, snap_name, target_device_id):
                    kwargs['wait_for_sync_called'] = True
        except Exception:
            exception_message = _('Issue    encountered    waiting    for    synchronization.')
            LOG.exception(exception_message)
            raise exception.VolumeBackendAPIException(data=exception_message)
        if (kwargs['retries'] > int(extra_specs[utils.RETRIES])):
            LOG.error('_wait_for_sync    failed    after    %(retries)d    tries.', {'retries': retries})
            raise loopingcall.LoopingCallDone(retvalue=int(extra_specs[utils.RETRIES]))
        if kwargs['wait_for_sync_called']:
            raise loopingcall.LoopingCallDone()
    kwargs = {'retries': 0, 'wait_for_sync_called': False}
    timer = loopingcall.FixedIntervalLoopingCall(_wait_for_sync)
    rc = timer.start(interval=int(extra_specs[utils.INTERVAL])).wait()
    return rc
