How can we pass Associative Array or SGNode to task thread from render thread without losing the values? In the following example, I am adding the request in a queue in the render thread but when in the go function, which is in the task thread, I try to access the request queue then it gives me an empty queue. How to Solve the issue?
sub init()
print "UriHandler.brs - [init]"
m.Port = createObject("roMessagePort")
m.top.numBadRequests = 0
m.requestQueue = createObject("roArray", 10, true)
m.processing = false
m.top.functionName = "go"
m.top.control = "RUN"
m.top.observeField("request", "addToQueue")
end sub
function addToQueue(data)
m.requestQueue.push(data.getData())
end function
'Task function
sub go()
print "UriHandler.brs - [go]"
' Holds requests by id
m.jobsById = {}
' UriFetcher event loop
while true
msg = wait(0, m.port)
mt = type(msg)
print "--------------------------------------------------------------------------"
print "Received event type '"; mt; "'"
' If a request was made
if mt = "roSGNodeEvent"
if msg.getField()="request"
print "got a request"
if m.requestQueue.count()>0
ProcessRequest(m.requestQueue.shift())
end if
else
print "Error: unrecognized field '"; msg.getField() ; "'"
end if
' If a response was received
else if mt="roUrlEvent"
processResponse(msg)
' Handle unexpected cases
else
print "Error: unrecognized event type '"; mt ; "'"
end if
end while
end sub
' function ProcessNextRequest()
' request = m.requestQueue.shift()
' ProcessRequest(request)
' print "setting processing false"
' end function
function ProcessRequest(request as Object) as Boolean
print "HTTPHandler - [addRequest]"
if type(request) = "roAssociativeArray"
print request
context = request.context
if type(context) = "roSGNode"
parameters = context.parameters
if type(parameters)="roAssociativeArray"
headers = parameters.headers
method = parameters.method
uri = parameters.uri
bodyString = ""
if method = "POST" or method = "PUT"
body = parameters.body
bodyString = body.toStr()
end if
if type(uri) = "roString"
urlXfer = createObject("roUrlTransfer")
urlXfer.SetCertificatesFile("common:/certs/ca-bundle.crt")
urlXfer.InitClientCertificates()
urlXfer.setPort(m.Port)
urlXfer.setUrl(uri)
' Add headers to the request
for each header in headers
urlXfer.AddHeader(header, headers.lookup(header))
end for
print "headers are " headers
'should transfer more stuff from parameters to urlXfer
idKey = stri(urlXfer.getIdentity()).trim()
'Make request based on request method
'AsyncGetToString returns false if the request couldn't be issued
if method = "POST" or method = "PUT" or method = "DELETE"
urlXfer.setRequest(method)
ok = urlXfer.AsyncPostFromString(bodyString)
else
ok = urlXfer.AsyncGetToString()
end if
if ok then
m.jobsById[idKey] = {
context: request
xfer: urlXfer
}
else
print "send not successful"
end if
print "Initiating transfer '"; idkey; "' for URI '"; uri; "'"; " succeeded: "; ok
else
print "Error: invalid uri: "; uri
m.top.numBadRequests++
end if
else
print "Error: parameters is the wrong type: " + type(parameters)
return false
end if
else
print "Error: context is the wrong type: " + type(context)
return false
end if
else
print "Error: request is the wrong type: " + type(request)
return false
end if
print "--------------------------------------------------------------------------"
return true
end function
'Received a response
sub processResponse(msg as Object)
idKey = stri(msg.GetSourceIdentity()).trim()
job = m.jobsById[idKey]
if job <> invalid
context = job.context
parameters = context.context.parameters
uri = parameters.uri
print "Response for transfer '"; idkey; "' for URI '"; uri; "'"
result = {
code: msg.GetResponseCode(),
headers: msg.GetResponseHeaders(),
content: msg.GetString(),
}
print result
print "response headers"
print result.headers
job.context.context.response = result
m.jobsById.delete(idKey)
else
print "Error: event for unknown job "; idkey
end if
' ProcessNextRequest()
print "--------------------------------------------------------------------------"
end sub`
You can create a custom task component which extends the
Tasknode, with the additional interface fields you need.You can then create an instance of the newly created task node and pass the data you want to its fields.