Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Hosting Requirements /

What you need to consider when choosing a hosting provider and plan.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Quercus and Google App Engine


Go to End


8 Posts   5898 Views

Avatar
ylluminate

Community Member, 24 Posts

28 January 2010 at 5:31pm

Has anyone played with getting SilverStripe to work with Quercus? Drupal has seen 4x performance improvements simply by running it atop Quercus and it stands to reason that SilverStripe would see these improvements.

Further, if this is accomplished it would only make sense to extend this further by getting this to work with Google App Engine. This would be phenomenal in terms of performance, but would perhaps require some retooling of the ORM for BigTable. Super project and would be ideal for the Google Summer of Code, but... we'd like to see it sooner. :)

Avatar
Sigurd

Forum Moderator, 628 Posts

28 January 2010 at 9:06pm

I've not heard anyone yet talking about Quercus, but you're most welcome to try it out, post any issues, and work towards supporting it. Getting SilverStripe to run on Google App Engine is likely to intrigue some people.

I assume that the 4x improvement reduces to 2x (or perhaps lower) when you compare SilverStripe running with a PHP bytecode cache such as xcache?

Avatar
meganjo

Community Member, 5 Posts

2 February 2010 at 5:36pm

Avatar
meganjo

Community Member, 5 Posts

2 February 2010 at 5:48pm

Avatar
ylluminate

Community Member, 24 Posts

6 February 2010 at 4:41am

Sounds good Sigurd. I'll put that on my list for the mid term. Very interesting and powerful to say the least, especially with the hosting costs and potential performance benefits. The problem we would have to work around are the different paradigms for BigTable and perhaps issues with Exploding Indexes and Big Entities, but I'm not certain if that will be an issue yet here as I've not done quite enough yet.

Avatar
dean_curly

Community Member, 4 Posts

2 March 2010 at 11:28pm

So, has anyone tried to install SS under Quercus?

Avatar
ylluminate

Community Member, 24 Posts

13 August 2010 at 6:20pm

Sounds like the key here is to get it working with Quercus first and then work on getting things converted over to GAE. I've not fiddled yet as I've been so tied up in other projects, but this really has serious potential.

Avatar
Stuckinrealtime

Community Member, 2 Posts

26 January 2012 at 7:11pm

I just started trying to get silverstripe 2.4.5 working under Quercus after a few tweaks with url rewriting and how urls are passed to silverstripe the only problem seems to be how some of the statics are returned from Object::get_static which prevents forms and full database builds from working.

I did need to add the following code to sapphire to get things to even begin to load

sapphire/core/Core.php to correct a problem with interfaces not being loaded or found


// load interfaces manually for some reason they are being missed by the manifest builder and autoload
$_interface_list = array(
    'core/i18nEntityProvider.php' ,
    'core/model/CurrentPageIdentifier.php'  ,
    'core/control/NestedController.php',
    'core/model/DataObjectInterface.php',
    'core/model/HiddenClass.php',
    'core/model/fieldtypes/CompositeDBField.php',
    'security/PermissionProvider.php'
);
foreach($_interface_list as $_interface_class) {
    require_once($_interface_class);
}

sapphire/main.php to get the stuff from my custom rewrite rules in. I added it before the IIS check

if(isset($_SERVER['SERVER_SOFTWARE']) && (strpos($_SERVER['SERVER_SOFTWARE'],'Apache PHP Quercus') !== false)) {
    $_quercus_url = $_quercus_request->getAttribute('SS_URL');
    $_quercus_qs = $_quercus_request->getAttribute('SS_QS');
    $_SERVER['REQUEST_URI'] = $_quercus_url;
    $url = $_quercus_url;
    if (!empty($_quercus_qs)) {
        parse_str($_quercus_qs,$_GET);
        if ($_GET) $_REQUEST = array_merge((array)$_REQUEST, (array)$_GET);
    }

}

I was wondering if anybody else has done any work in this area.

FYI: this is my setup

jetty-8.0.4.v20111024 from http://jetty.codehaus.org/jetty/
urlrewrite filter verson 4.0 from http://code.google.com/p/urlrewritefilter/
quercus-4.0.18 from http://www.caucho.com

Servlet Mapping for Quercus from web.xml:

<servlet>
    <servlet-name>Quercus Servlet</servlet-name>
    <servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>
    <init-param>
      <param-name>script-encoding</param-name>
      <param-value>ISO-8859-1</param-value>
    </init-param>
    <init-param>
          <param-name>ini-file</param-name>
          <param-value>WEB-INF/php.ini</param-value>
    </init-param>
</servlet>
<servlet-mapping>
        <servlet-name>Quercus Servlet</servlet-name>
        <url-pattern>*.php</url-pattern>
</servlet-mapping>

UrlRewriteFilter config from web.xml

    <filter>
        <filter-name>UrlRewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
        <init-param>
            <param-name>logLevel</param-name>
            <param-value>DEBUG</param-value>
        </init-param>
        <init-param>
            <param-name>modRewriteConf</param-name>
            <param-value>false</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>UrlRewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

urlrewrite.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
        "http://tuckey.org/res/dtds/urlrewrite4.0.dtd">

<urlrewrite>

    <rule>
        <note>
            The rule means that requests to /test/status/ will be redirected to /rewrite-status
            the url will be rewritten.
        </note>
        <from>/test/status/</from>
        <to type="redirect">%{context-path}/rewrite-status</to>
    </rule>

    <!-- invoke special rule for silverstripe -->
    <class-rule class="org.silverstripe.web.filters.SSPrettyUrlRewriteRule" />



    <outbound-rule>
        <note>
            The outbound-rule specifies that when response.encodeURL is called (if you are using JSTL c:url)
            the url /rewrite-status will be rewritten to /test/status/.

            The above rule and this outbound-rule means that end users should never see the
            url /rewrite-status only /test/status/ both in thier location bar and in hyperlinks
            in your pages.
        </note>
        <from>/rewrite-status</from>
        <to>/test/status/</to>
    </outbound-rule>


</urlrewrite>

Custom Java Rules (I couldn't get the regular ones working properly for silverstripe)

#1) SSPrettyUrlRewriteMatch.java

package org.silverstripe.web.filters;

/**
 * Created by IntelliJ IDEA.
 * User: smathews
 * Date: 1/24/12
 * Time: 10:18 PM
 */

import org.tuckey.web.filters.urlrewrite.extend.RewriteMatch;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SSPrettyUrlRewriteMatch extends RewriteMatch {

    public boolean execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String qs = request.getQueryString();
        String url = request.getRequestURI();
        
        // this these as server variables so php can see them
        request.setAttribute("SS_QS",qs);
        request.setAttribute("SS_URL",url);

        String forwardto = "/sapphire/main.php";
        RequestDispatcher rd = request.getRequestDispatcher(forwardto);

        rd.forward(request, response);

        return true;
    }
}

#1) SSPrettyUrlRewriteRule.java

package org.silverstripe.web.filters;

/**
 * Created by IntelliJ IDEA.
 * User: smathews
 * Date: 1/24/12
 * Time: 10:01 PM
 */

import org.tuckey.web.filters.urlrewrite.extend.RewriteRule;
import org.tuckey.web.filters.urlrewrite.extend.RewriteMatch;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;

public class SSPrettyUrlRewriteRule extends RewriteRule {
    
    private boolean isFile(String filename) {
        boolean exists = false;
        try {
            File f = new File(filename);
            exists = f.isFile() && f.exists();
        } catch(Exception e) {
            exists = false;
        }
        return exists;
    }
    
    public RewriteMatch matches(HttpServletRequest request, HttpServletResponse response) {

        // we don't want to match request from
        if (request.getRequestURI().startsWith("/sapphire/main.php")) return null;

        // ignore all image types
        if (request.getRequestURI().startsWith(".ico")) return null;
        if (request.getRequestURI().startsWith(".png")) return null;
        if (request.getRequestURI().startsWith(".gif")) return null;
        if (request.getRequestURI().startsWith(".mov")) return null;
        if (request.getRequestURI().startsWith(".jpg")) return null;

        String fileName = request.getServletContext().getRealPath(request.getRequestURI());

        // we don't process any request if there is an actual file
        if (this.isFile(fileName)) return null;

        return new SSPrettyUrlRewriteMatch();


    }
}