Skip to content

Photos uploading takes forever, when it goes from client to server #314

@VasylKhmil

Description

@VasylKhmil

After spending some time figuring out what is an issue, I found out that methods
private func readBody(_ socket: Socket, size: Int) throws -> [UInt8]
were using this line to get data passed for _ in 0..<size { body.append(try socket.read()) }

Here is a method read() from Socket class:

open func read() throws -> UInt8 {
        var buffer = [UInt8](repeating: 0, count: 1)
        #if os(Linux)
            let next = recv(self.socketFileDescriptor as Int32, &buffer, Int(buffer.count), Int32(MSG_NOSIGNAL))
        #else
            let next = recv(self.socketFileDescriptor as Int32, &buffer, Int(buffer.count), 0)
        #endif
        if next <= 0 {
            throw SocketError.recvFailed(Errno.description())
        }
        return buffer[0]
    }

I can see that you're trying to load size of one byte. As a result combination of this two methods wors really slow for photo sending(need to perform read method approximately 6 000 000 times).

I've added a variation of read methods, where you can specify length to read:

open func read(length: Int) throws -> [UInt8] {
        var buffer = [UInt8](repeating: 0, count: length)
        #if os(Linux)
        let next = recv(self.socketFileDescriptor as Int32, &buffer, Int(buffer.count), Int32(MSG_NOSIGNAL))
        #else
        let next = recv(self.socketFileDescriptor as Int32, &buffer, Int(buffer.count), 0)
        #endif
        if next <= 0 {
            throw SocketError.recvFailed(Errno.description())
        }
        return Array(buffer.prefix(next))
    }

As well changed private func readBody(_ socket: Socket, size: Int) throws -> [UInt8]
to read as big chunks as possible(pasting with modifications that was made, please pay attention on signs on left side):

     private func readBody(_ socket: Socket, size: Int) throws -> [UInt8] {
         var body = [UInt8]()
-        for _ in 0..<size { body.append(try socket.read()) }
+        var length = size
+        while length > 0 {
+            let buffer = try socket.read(length: length)
+            body.append(contentsOf: buffer)
+            length -= buffer.count
+        }
         return body
     }

I'm wondering why there was reading by one byte? Did I make it correctly, or maybe you tried preventing another issue, that may happen for me with this new way of data getting?
So far now it works fast and seems I did not receive any issue with that yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions