In one of my Controllers, I have multiple URLs that will ultimately render in the same way. For example, this method scans the network on which the server resides, caches a String representation of each connected device and each device listening on a specific port, and then sends that information to another method to render:
public static void networkScan(String networkTarget, String port)
{
//These two lists will never have more than 256 total entries
List<InetSocketAddress> listeningDevices;
Map<String, String> allDevices;
...Logic for discovering network devices...
//Store the results in a cache, for history preservation in the browser
Cache.set(session.getId() + "listeningDevices", listeningDevices);
Cache.set(session.getId() + "allDevices", allDevices);
showScan(listeningDevices, allDevices);
}
public static void showScan(List<InetSocketAddress> listeningDevices, Map<String, String> allDevices)
{
render(listeningDevices, allDevices);
}
public static void getCachedScan()
{
List<InetSocketAddress> listeningDevices = (List<InetSocketAddress>)Cache.get(session.getId() + "listeningDevices");
Map<String, String> allDevices = (Map<String, String>)Cache.get(session.getId() + "allDevices");
if(listeningDevices == null)
listeningDevices = new ArrayList<InetSocketAddress>();
if(allDevices == null)
allDevices = new TreeMap<String, String>();
renderScan(listeningDevices, allDevices);
}
Doing it this way results in Play doing some weird array copying that ends up taking infinite memory. If I were to change my call of showScan() to simply render() and create a view with the name networkScan.html, it all works just fine, no memory bugs.
I have several other methods that also use showScan, based on different caching settings. I don’t want lots of views that are all essentially copies of each other, so I’m trying to go through just one method with one corresponding view.
Turns out that calling an action method creates a redirect event, which resulted in all sorts of copying objects into URLs. I still don’t understand how that mushroomed into using over a gigabyte of memory for a collection of Strings that rarely numbered above 100, and never above 256, but I found a way of avoiding the redirect event.
As I was directed to do in an answer on Google Groups, I made use of the
@Utilinterceptor on the showScan method:Marking a method with
@Utilunfortunately makes it use the template of the calling method, but the call torenderTemplate()allows me to use a single template that I specify.