Jan 29, 2013

How to configure fastcgi(mod_fcgid) for apache.

Install mod_fcgid if not yet install.
yum install mod_fcgid

Edit http.conf, but be sure to backup before do any changes.
DocumentRoot "/var/www/html"

# FcgidMaxRequestsPerProcess should be <= PHP_FCGI_MAX_REQUESTS
# The example PHP wrapper script overrides the default PHP setting.
FcgidMaxRequestsPerProcess 10000

# Uncomment the following line if cgi.fix_pathinfo is set to 1 in
# php.ini:
# FcgidFixPathinfo 1

.....

<Document "/var/www/html">
AddHandler fcgid-script .php
Options +ExecCGI
FcgidWrapper /usr/bin/php-wrapper .php

.......

</Document>

As you notice I did not use an Alias to specific directory. Since, I decide to use fast-cgi rather than mod_php, I modify Document either.


Create the wrapper file /user/bin/php-cgi-wrapper
#!/bin/sh
# Set desired PHP_FCGI_* environment variables.
# Example:
# PHP FastCGI processes exit after 500 requests by default.
PHP_FCGI_MAX_REQUESTS=10000
export PHP_FCGI_MAX_REQUESTS

# Replace with the path to your FastCGI-enabled PHP executable
exec /usr/bin/php-cgi

Change the wrapper permission to executable.
chmod 755 /user/bin/php-cgi-wrapper

Jan 28, 2013

GAE - How to to handle DeadlineExceededException

Before we do. Lets recap how this Exception encounter or what is the cause?

This Exception encounter when a request runtime exceed the 60 sec runtime. Some you are working with loop.


Lets take some example. Somehow you are looping some data and update some properties of every record.


Possible solutions/workaround

Somehow you must have extract servlet the equivalent process to every record. Lets take you have servlet /updateData and /updateDataBackend. You updateDataBackend will process the other data that will possible reach by Deadline. By the use getRemainingMillis() method you can able determine if the extra will be reach by Deadline.



/updateDataBackend

import com.google.apphosting.api.ApiProxy;

...

for(Entity ent : myDataEntities){
  if (ApiProxy.getCurrentEnvironment().getRemainingMillis() > 5000){
     // I think 5 seconds can still do the job
  // Update data
  }else{
    // Opps, It almost reach DeadlineExceededException better create a backend procress
    // for extra data
    //  Please the updateDataBackend to run in backend
  }
}

Hope that helps. Also try to read The_Request_Timer

Happy reading

Jan 18, 2013

Getting Stated on Spring MVC with Google AppEngine

Since, Appengine was the best free java server to deploy application. This is why good to integrate java frameworks to google appengine.

As this point, assume that you already create your Google Appengine project. However if you don't know how to create GAE project go here.

Pre-requisites:
* Eclipse Kepler + Spring 3.2.4 + Google App Engine 1.9.7 + Java 7
* Download Spring jars
Extract the zip files and copy jars to war/WEB-INF/lib/(for deployment) and include the jars in project library.

1. Create mv-dispacher-servlet.xml.
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
 
 <!-- 
        Component 
        https://developers.google.com/appengine/articles/spring_optimization
 -->
 <!-- 
 <context:component-scan base-package="com.winzter.springmvc.controllers">
  <context:exclude-filter type="regex" expression="com.winzter.springmvc.controllers.GuessController.*" />
 </context:component-scan>
    -->
 
 <!-- DEFINE Your bean Here -->
  <bean class="com.winzter.springmvc.controllers.GuessController" />
  <bean  class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
   <bean class="com.winzter.airgames.bigbarnword.controllers.FriendsController" />
 
 <mvc:annotation-driven />
  
 <!-- Bean to show you Di in GAE, via Spring, also init the MovieController -->
 <bean class="com.winzter.springmvc.controllers.GuessController">
  <property name="message">
   <value>Hello World</value>
  </property>
  <!--constructor-arg name="message" value="Help ET go home" /-->
 </bean>
 <!-- bean class="com.winzter.airgames.bigbarnword.controllers.FriendsController">
  <property name="message">
   <value>Hello World</value>
  </property>
 </bean-->
  
 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 
 <!-- 
  This serve for JSPs
  Every controller menthod return string, it file /pages/string.jsp 
 -->
  <property name="prefix">
   <value>/</value>
  </property>
  
  <property name="suffix">
   <value>.jsp</value>
  </property>
 </bean>

</beans>

2. Update/add code below to web.xml
<servlet>
  <servlet-name>mvc-dispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>mvc-dispatcher</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>