# Reports in their own thread

**URL:** <https://forum.inductiveautomation.com/t/reports-in-their-own-thread/28507>\
**Category:** Ignition\
**Tags:** ignition79\
**Created:** [September 24, 2019, 2:38pm UTC](https://forum.inductiveautomation.com/t/reports-in-their-own-thread/28507 "2019-09-24T14:38:19Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![salbrechtsen](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/salbrechtsen/32/18660_2.png) [@salbrechtsen](https://forum.inductiveautomation.com/u/salbrechtsen)\
**Post date:** [September 24, 2019, 2:38pm UTC](https://forum.inductiveautomation.com/t/reports-in-their-own-thread/28507/1 "2019-09-24T14:38:19Z")

</div>

I have a couple general questions about reports, wondering if anyone has encountered these before.

1. If I have a report, with 2 report schedules with email actions at the same time, are these reports executed and distributed on their own thread?

2. Is there any way, in scripting, to call something like `system.report.executeAndDistribute` in its own thread? The [docs](https://docs.inductiveautomation.com/display/DOC79/system.report.executeAndDistribute) say `system.report.executeAndDistribute() does not run on its own thread and can get blocked.`

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [September 24, 2019, 3:04pm UTC](https://forum.inductiveautomation.com/t/reports-in-their-own-thread/28507/2 "2019-09-24T15:04:19Z")

</div>

That’s what [invokeAsynchronous](https://docs.inductiveautomation.com/display/DOC80/system.util.invokeAsynchronous) is for. Not just for reporting.

---

<div class="post-metadata">

**Author:** ![salbrechtsen](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/salbrechtsen/32/18660_2.png) [@salbrechtsen](https://forum.inductiveautomation.com/u/salbrechtsen)\
**Post date:** [September 24, 2019, 3:15pm UTC](https://forum.inductiveautomation.com/t/reports-in-their-own-thread/28507/3 "2019-09-24T15:15:40Z")

</div>

The reason I ask is since the `executeAndDistribute` docs explicitly state it runs on a shared thread I was wondering if it would even work to call `system.util.invokeAsynchronous`. Perhaps all that would do is asynchronously invoke `executeAndDistribute` which would place the report in some kind of que on a shared thread and still have the same blocking problem?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [September 24, 2019, 3:48pm UTC](https://forum.inductiveautomation.com/t/reports-in-their-own-thread/28507/4 "2019-09-24T15:48:06Z")

</div>

Per the manual:

> the given function will start executing asynchronously on a different thread.

executeAndDistribute() itself will not return to its caller until complete or failed.

If in doubt, you can also subclass `java.lang.Runnable`, implement your code as the run() method, then create and start a `java.lang.Thread` with that runnable. This latter approach allows you to name the thread for less cryptic gateway monitoring.

---

<div class="post-metadata">

**Author:** ![salbrechtsen](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/salbrechtsen/32/18660_2.png) [@salbrechtsen](https://forum.inductiveautomation.com/u/salbrechtsen)\
**Post date:** [September 24, 2019, 4:16pm UTC](https://forum.inductiveautomation.com/t/reports-in-their-own-thread/28507/5 "2019-09-24T16:16:31Z")

</div>

I was thinking for some reason executeAndDistribute returned immediately because it returned nothing. I just did a test and it behaves how you described when I call invokeAsynchronous. Thanks!

---

<div class="post-metadata">

**Author:** ![salbrechtsen](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/salbrechtsen/32/18660_2.png) [@salbrechtsen](https://forum.inductiveautomation.com/u/salbrechtsen)\
**Post date:** [September 24, 2019, 5:24pm UTC](https://forum.inductiveautomation.com/t/reports-in-their-own-thread/28507/6 "2019-09-24T17:24:14Z")

</div>

I thought it was working initially until I did this test.

```auto
from functools import partial
from system.report import executeAndDistribute

path = "Development/Timing"
project = "Reports"
action = "email"
actionSettings = {
	"smtpServerName": "SMTP1_1",
	"from": "noreply@tanklogix.com",
	"to": ["salbrechtsen@tanklogix.com"],
	"subject": "Timing Report",
	"fileType": "pdf",
	"attachmentName": "report.pdf"
}

parameters = {
	"SleepSeconds": 60
}
system.util.invokeAsynchronous(partial(executeAndDistribute, path, project, parameters, action, actionSettings))

for i in range(3):
	parameters = {
		"SleepSeconds": 0
	}
	actionSettings["subject"] = "Timing Report %i" % i
	system.util.invokeAsynchronous(partial(executeAndDistribute, path, project, parameters, action, actionSettings))

```

The timing report just does a `time.sleep()` using the SleepSeconds parameter in a script, and then prints out the start and end time of the report. [TimingReport.proj](https://us1.discourse-cdn.com/inductiveautomation/original/2X/4/4c651cf3c3776dd93c774ec08639110e87555753.proj) (6.6 KB)

I expected to get 3 emails with the subjects “Timing Report 0”, “Timing Report 1”, and “Timing Report 2”. Then ~1 minute later another email with the subject “Timing Report”. The emails came in with the correct timing and contents, however, all 4 subject lines read “Timing Report 4”. On running this a few times, I got a variety of email subjects.

It appears there are race conditions when calling executeAndDistribute with invokeAsynchronous. Doing this does not appear to be thread safe. It appears each report can only execute one action at a time and it is a shared resource. This is probably why IA docs state the possibility of blocking on execute and distribute, it has to wait for the last action to finish, otherwise it will be overwritten.

Next, I’m going to try calling `system.report.executeReport` asynchronously and sending my own email with `system.net.sendEmail` when I get the report bytes back.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [September 24, 2019, 5:38pm UTC](https://forum.inductiveautomation.com/t/reports-in-their-own-thread/28507/7 "2019-09-24T17:38:11Z")

</div>

You re-used actionSettings, so every execution got whatever the `subject` key held at the time it looked for each phase of the report. There is overhead starting a new thread, which prevented the latter threads from catching the correct subject. I’m not sure how you got “Timing Report 4”.

These race conditions are on you. Don’t re-use lists or dictionaries in multiple threads, unless you are using them to communicate between threads.

---

<div class="post-metadata">

**Author:** ![salbrechtsen](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/salbrechtsen/32/18660_2.png) [@salbrechtsen](https://forum.inductiveautomation.com/u/salbrechtsen)\
**Post date:** [September 24, 2019, 6:01pm UTC](https://forum.inductiveautomation.com/t/reports-in-their-own-thread/28507/8 "2019-09-24T18:01:39Z")

</div>

Nice catch! I didn’t think about python essentially passing by reference there. Made sure I was giving it a new actionSettings each time and it seems to be working.
