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 Task
node, with the additional interface fields you need.
<?xml version="1.0" encoding="UTF-8"?>
<component name="CustomTask" extends="Task">
<interface>
<field id="aaField" type="assocarray"/>
<field id="nodeField" type="node" />
</interface>
</component>
sub init()
m.top.functionName = "getContent"
end sub
sub getContent()
? m.top.aaField ' Prints the associative array passed
? m.top.nodeField ' Prints the SG node passed
end sub
You can then create an instance of the newly created task node and pass the data you want to its fields.
contentNode = createObject("roSGNode", "ContentNode")
m.someTask = createObject("roSGNode", "CustomTask")
m.someTask.aaField = { hello: "world" }
m.someTask.nodeField = contentNode
m.someTask.control = "run"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.