<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read(self, offset, length, fh):
 """ Read data. Method returns data instantly, if they're avaialable and in ``self.safe_range``. Otherwise data is downloaded and then returned. Parameters offset : int Read offset length : int Length of data to read. fh : int File descriptor. """


        current = (offset, offset + length)

        safe = [ current[0] - ( 8 * length ), current[1] + ( 16 * length ) ]
        if safe[0] < 0: safe[0] = 0
        if safe[1] > self.filesize: safe[1] = self.filesize
        safe = tuple(safe)

        self.lock.acquire()

        try:
            dl = range_t({safe}) - self.avail

            for r in dl.toset():
                try:
                    Downloader.fetch(self, r, fh) # download is, let's say, atomic thanks to lock
                except requests.exceptions.ConnectionError:
                    raise ConnectionError

            if self.disk + 1 < len(self.avail):

                self.data.rollover()
                self.disk += 1

        finally:
            self.lock.release()

        self.data.seek(offset)
        return self.data.read(length)