Example not work - Coroutines and sync http requests (SOLVED)

https://forum.defold.com/t/coroutines-and-sync-http-requests/66387

Please suggest a solution to the problem.
Why is the example not working?

defold 1.3.4

Please post text, and not screen shots. It is a lot easier for us to read, and search through and also test.

sorry, my mistake

i’m get it from this post

local function http_request(url, method)
	local co = coroutine.running()
	http.request("http://d.defold.com/stable/info.json", "GET", function(self, id, response)
		print('result is fetched')
		coroutine.resume(co, response)
	end)
	return coroutine.yield()
end

local co = coroutine.create(function()
	print('request is executed')
	local response = http_request("http://d.defold.com/stable/info.json", "GET")
	print('should not be executed before fetched result')
end)

local ok, err = coroutine.resume(co)

why do I need it

global_["host_name"] = {'http://127.0.0.1',  'http://127.0.0.1:2347'}

function load_init_callback(self, _, response)
	pprint(response)
end
	
for key, value in pairs(global_.host_name) do
    http.request(value .. '/?action=' .. global_.init_url, "POST", load_init_callback, global_.header, '')
end

but i cant get the table index for responded server
i have alvays 2 because request is async

1 Like

It looks like you are creating and running that coroutine outside of the lifecycle functions. This will not work. You need to create and start the coroutine from init, on_input or similar function.

I’m not really sure what it is you wish to do? Could you please explain what you want to achieve?

Thank you. try in initialization

Let’s say there are several servers.

The client will connect to the first working server

but I can’t find its index in the address table

thank you very much)) everything works. I will put the value of the key in the loop into a global variable and will use it in other queries

http.request(global_.host_name[key], method)

since we already know the address of the working server)))

global_ = {}
global_["host_name"] = {'http://127.0.0.1:2347', 'http://127.0.0.1'}

local function http_request(url, method)
	local co = coroutine.running()
	http.request(url, method, function(self, id, response)
		print('result is fetched')
		coroutine.resume(co, response)
	end)
	return coroutine.yield()
end

function init(self)
	for key, value in pairs(global_.host_name) do

		local key = coroutine.create(function()
			print('request is executed')
			local response = http_request(value, "GET")

			pprint(response)
			pprint(key)
			
			print('should not be executed before fetched result')
		end)

		local ok, err = coroutine.resume(key)
		
	end	

end

You are creating one coroutine for each iteration of the loop. If you want to try the servers one after the other then create one coroutine outside of the for-loop.

1 Like

:+1: :sweat_smile:

How to do it? I do not understand
please :roll_eyes:

	local co = coroutine.create(function()

		for key, value in pairs(global_.host_name) do
		
			print('request is executed')
			local response = http_request(value, "GET")

			pprint(response)
			pprint(key)
			
			print('should not be executed before fetched result')

		end	
			
	end)

	local ok, err = coroutine.resume(co)

it`s right answer?

Yes, that is right. Did you try it yourself? You should see it do one http request, wait for the response, and then do the next one.

With your previous solution you did both at the same time.

I recommend that you try things yourself, add logging or use the debugger, and check if results are as you expect them to be.

Thank you very much britzl

Everything works as it should.

The application starts up noticeably longer if one of the servers does not respond. This is how time is spent waiting for a response from the server.