Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks!

I'm integrating two sets of code, one written for a Dancer web app, the other for CGI.pm. There's core code in the Dancer app that runs, and then the request parameters are parsed, the appropriate modules loaded, and the route-specific code is run, returning either a data structure (Dancer app) or printing to STDOUT (CGI.pm code). The content is then rendered in a template that also has page header, footer, navigation, etc., generated by the Dancer app.

I'm running into various problems because of the way that the CGI.pm-based code is written, e.g. some of the modules auto-export all their functions into the global namespace, most of the modules initialise a load of request-specific variables on load, there are function name clashes between modules, and most were written without warnings (and some without strict mode) turned on. From my understanding of the way Dancer is operating, the Dancer app stays alive between requests, so the CGI.pm modules really need to be reloaded to reinitialise these request-specific variables. Additionally, some of the functionality in the CGI.pm modules takes a long time to execute (it was written before the days of AJAX) and might be better dealt with by presenting a 'loading' page in the UI and retrieving the data via javascript when it is ready.

Is there a way to temporarily / safely execute the CGI.pm-based code within the Dancer framework without running into the issues above? Some kind of sandbox around the code, like a big eval but which also prevents namespace pollution (and ideally "unloads" the modules after use)? To recap, I'd like to:

Apologies if this is not clearly enough described. I can provide more detail if helpful. Thank you in advance for any suggestions!

  • Comment on Integrating codebases: namespace pollution, passing objects, and more
  • Download Code

Replies are listed 'Best First'.
Re: Integrating codebases: namespace pollution, passing objects, and more
by Anonymous Monk on Feb 27, 2017 at 18:04 UTC
    I would rewrite the CGI code. Should take less time than trying to make your existing code work, which will at best be no better than a leaky abstraction. So rewrite the code now and be thankful for it tomorrow.
      The codebase is huge -- 350+ modules, written in a mixture of procedural and OO styles, no separation of concerns (e.g. html and js mixed in with perl), no tests, etc. Rewriting it would be optimal but not practical for my current circumstances, which is why I would like to "sandbox" the old code somehow so I can use it without too much modification.

        One possible way to sandbox the CGI code is to run it in it's own process or thread. Depending on that code's behavior, you might not have to destroy the thread/process after each request.

        Another possibility is to let the webserver run it and have your Dancer app either send a redirect to the user's webbrowser, or send it's own HTTP request to the webserver. Obviously, if you go the redirect route, the CGI app wil have to be modified to include a redirect back to the Dancer app in it's response to the webbrowser's request.

        So just sandbox a bunch of old crap and hope it holds up, again, for another 10 years ... good luck with that.
Re: Integrating codebases: namespace pollution, passing objects, and more
by Anonymous Monk on Feb 28, 2017 at 02:13 UTC

    Is there a way to temporarily / safely execute the CGI.pm-based code within the Dancer framework without running into the issues above?

    Simples way to do that is fork+exec, just like how "cgi-bin" works

    You could investigate CGI::Compile ... but if the code is as poor as you say :)