Riot Games utilizes Confluence DC as a company-wide intranet, and we’ve adapted it for some unconventional purposes such as displaying real-time weekly lunch/dinner menus for our cafeteria and posting industry-related news articles. Recently, we used the ScriptRunner plugin to turn Confluence into a livestreaming video platform. Since we encountered performance problems early on, I thought it would be interesting to discuss our approach here.
We needed a way to livestream and we wanted to host on our newly rolled-out Confluence DC to prove its successful usage as an intranet. Our first attempt at livestreaming video on a Confluence page resulted in our instance being unresponsive at about 100 concurrent viewers. Per our monitoring system, we saw a tremendous spike in the JVM process while the livestream was up, and an immediate drop to normal levels when the livestream concluded. Following the stream, we simulated multiple users trying to view a video on a Confluence page (video file attachment, Youtube clip, live Twitch stream, and “test” internal livestream) to check whether Confluence is able to handle such a task. After successfully making Confluence unresponsive with simulated load testing, we found that Confluence innately isn’t designed to be a multimedia host, let alone a livestream viewing platform concurrently viewed by many users. Since we needed to support thousands of Rioters around the world and sought to leverage our new Confluence-backed intranet, we tried to find a solution that would allow us to hold a performant livestream without compromising the performance of Confluence itself.
Luckily, ScriptRunner includes Script REST Endpoints, which allow the creation of custom dialogs. You can see how in the official documentation by Adaptavist.
Something to note is that the full REST endpoint URL (e.g. https://<Confluence URL>/rest/scriptrunner/latest/custom/showDialog) is an address that users can hit directly in the browser. Granted, hitting the URL directly won't produce a nicely formatted dialog. Using the code from the above screenshot, hitting the REST endpoint URL directly produces the following webpage:
Please note that this is a page that exists outside of Confluence, meaning directing user traffic here won't impact the performance of the actual Confluence instance. Since HTML is ultimately returned at the end through:
Response.ok().type(MediaType.TEXT_HTML).entity(dialog.toString()).build();
The content of the dialog variable can be a full HTML document with internal CSS within the <head> section. As for placing the livestream video, we utilized <iframe> tag inside the HTML code. As a result, we were able to produce this:
One powerful advantage of using a REST endpoint is that it's recyclable. For subsequent livestream events, we can just swap out the src value within the <iframe> tag. The downside is that REST endpoints bypass login; anyone who has the knowledge of the REST endpoint URL can access the page without logging in to Confluence. Even if your Confluence instance is behind a firewall, this posesproposes some security concerns. Fortunately, you can declare a groups attribute when creating the REST endpoint, as shown in the ScriptRunner for documentation:
This forces users to log in to Confluence before being able to hit the REST endpoint. In Riot's case, we sent out a company-wide notice to direct users to a Confluence page that contained the link to the livestream page. By doing so, the AD group information of the user was captured at login, and the REST endpoint checked whether the user belonged in the group specified in the groups attribute.
The ability to create a brand new static HTML page that acts as an extension to Confluence has many powerful applications. Some examples I can foresee us utilizing this feature for are:
Happy scripting!
Rei Song
Engineering Manager - Atlassian Tools
0 comments