chrysn / aiocoap

The Python CoAP library
Other
267 stars 120 forks source link

time delay in requests due to _append_response_block #368

Open Koushik-ak47 opened 1 month ago

Koushik-ak47 commented 1 month ago
Python version: 3.11.2 (tags/v3.11.2:878ead1, Feb  7 2023, 16:38:35) [MSC v.1934 64 bit (AMD64)]
aiocoap version: 0.4.11
Modules missing for subsystems:
    dtls: missing DTLSSocket
    oscore: everything there
    linkheader: everything there
    prettyprint: everything there
    ws: missing websockets
Python platform: win32
Default server transports:  oscore:tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver
Selected server transports: oscore:tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver
Default client transports:  oscore:tcpclient:tlsclient:simple6
Selected client transports: oscore:tcpclient:tlsclient:simple6
SO_REUSEPORT available (default, selected): False, False

I have been trying to get data from file from a coap server using block mode transfer. I have been using the aiocoap client.py example code for GET method for this file transfer. I have recorded time for receiving a 100MB data from a sample file which is taking 2000-2200 seconds which approx. 45 mins.

I am attaching the client_get.py that I have used. import logging import asyncio

from aiocoap import *
import aiocoap.numbers as numbers
logging.basicConfig(level=logging.INFO)

async def main():
    protocol = await Context.create_client_context()

    #numbers.constants.TransportTuning.ACK_TIMEOUT = 5.0
    request = Message(code=GET, uri="coap://192.168.1.2:5683/get_service_log")
    # request.transport_tuning.ACK_TIMEOUT = 5.0

    try:
        response = await protocol.request(request).response
    except Exception as e:
        print("Failed to fetch resource:") 
        print(e)
    else:
        print("Result: %s\n%r" % (response.code, response.payload))

if __name__ == "__main__":
    asyncio.run(main())

I want to increase the data transfer and got to know from my debug that is because of the below function. assembled_response._append_response_block(last_response)

async def _complete_by_requesting_block2(
        cls, protocol, request_to_repeat, initial_response, log
    ):
        # FIXME this can probably be deduplicated against BlockwiseRequest

        if (
            initial_response.opt.block2 is None
            or initial_response.opt.block2.more is False
        ):
            initial_response.opt.block2 = None
            return initial_response

        if initial_response.opt.block2.block_number != 0:
            log.error("Error assembling blockwise response (expected first block)")
            raise error.UnexpectedBlock2()

        assembled_response = initial_response
        last_response = initial_response
        while True:
            current_block2 = request_to_repeat._generate_next_block2_request(
                assembled_response
            )

            current_block2 = current_block2.copy(remote=initial_response.remote)

            blockrequest = protocol.request(current_block2, handle_blockwise=False)
            last_response = await blockrequest.response

            if last_response.opt.block2 is None:
                log.warning(
                    "Server sent non-blockwise response after having started a blockwise transfer. Blockwise transfer cancelled, accepting single response."
                )
                return last_response

            block2 = last_response.opt.block2
            log.debug(
                "Response with Block2 option received, number = %d, more = %d, size_exp = %d.",
                block2.block_number,
                block2.more,
                block2.size_exponent,
            )
            try:
                assembled_response._append_response_block(last_response)
            except error.Error as e:
                log.error("Error assembling blockwise response, passing on error %r", e)
                raise

            if block2.more is False:
                return assembled_response

It is being triggered by BlockwiseRequest._complete_by_requesting_block2() in protocol.py

I have checked the definition of _append_response_block in message.py but didn't find solution to decrease the time delay. Can you please solve this issue to increase data transfer speed. I hope you to respond soon so that your valuable suggestion/solution might help me out in increasing the transfer speed.