Archived

This forum has been archived. Please start a new discussion on GitHub.

Problems with multiple requests from PHP5 to ICE/C++

Hi,
we are in a big trouble. Let me explain it to you.
We have developed a architecture based on multiple interfaces:
we had some PHP 5 classes which did some operations (Database query, input Form, etc.). We decided to translate these classes in c++, so, without changing PHP 5 interfaces, we changed PHP 5 classes with fake ones that call Ice with the respective c++ classes.
In this way:

- USER requests web page
- the PHP page instances an object(for example the class myDb.php which executes queries) :

$p = $GLOBALS["ICE"]->stringToProxy($DBProxy);
$p = $p->ice_twoway();
$p = $p->ice_secure(false);
$this->db = $p->ice_checkedCast("::MyCompany:database");

- this object connects to ICE, which calls myDb.cpp (ICE itself)
- myDb.cpp does some operations and fills a result (out parameter )
- the out parameter is taken by myDb.php and it is returned to a generic PHP 5 function which dinamically constructs the web page requested.

The problem is:
When two or more users on different computers are browsing the same website that uses this Ice - PHP structure
sometimes happens that the resulting pages are inverted (the page requested by USER A is displayed on the USER B's PC and vice-versa)

we only destroy the generic communicator in Server.cpp, not the ones created in the fake PHP classes
could be this the problem?

thanks in advance,
Jacopo

Comments

  • mes
    mes California
    Hi,

    Please update your signature as described in this post.

    Also, please provide as much information as possible about your environment, such as the exact versions of Ice, PHP, compiler, OS, Web server, etc.

    Take care,
    - Mark
  • Hi & sorry for our lack of signature and detailed informations.
    Now we updated it.

    We use:

    Debian testing
    Apache 1.3.34-2
    Php-5.0.4
    Ice-3.0.0 (no patches!!!)
    IcePHP-3.0.0
    sqlrelay-0.36.4-4
    postgresql-7.5.15
    gcc-3.4

    Our previous architecture was this:

    1) Some PHP files to develop custom client-side web page;
    2) Some PHP classes (Database, Menu, Form, List,...) which produce the core of our web applications, based on infomation stored in database;
    3) The Postgresql server which contains a database with tables for web pages format and custom tables to store information for different end-user applications.

    This is now our new architecture:

    1) Some PHP files to develop custom client-side web page;
    2) Some "fake" PHP classes which contain the calls to the ICE framework. This is a way to keeping the same interfaces between PHP files and classes, to switch safely from the previous architecture to the new one. (see Database.php and Menu.php);
    3) Some C++ classe based on your good framework. We have simply recoded the previous php classes in c++ classes (see config, Server.cpp, Database.cpp, Database.h, Menu.h, Menu.cpp);
    4) We produce one version querying directly postgresql server and another version using sqlrelay to access transparently to different kinds of DBMS;
    5) Some of C++ classes use other C++ classes (ex. Menu uses Database), calling them to a common endpoint and not directly as classic c++ classes. This is why the same classes are used by PHP Fake Classes and C++ framework Classes.

    Now we have finished recoding and debugging our software we have found a strange behaviour:
    when two or more users on different computers are browsing the same website that uses this Ice - PHP structure sometimes the resulting pages are inverted (the page requested by USER A is displayed on the USER B's PC and vice-versa).

    This happens when the requests are done simultaneously.

    Please, could you give us a little help?

    Many thanks in advance.
    Enrico, Jacopo & friends.
  • mes
    mes California
    Hi,

    If two web users are seeing inverted results, there must be a problem in the PHP client or your Ice server. Since Apache 1.x assigns a different child process to each web client, I think it's more likely that the problem is in your server.

    For example, I see that your Ice server opens a connection to a database. Is this connection safe to use from multiple threads? If not, this could explain the inverted results.

    I recommend doing some tests to ensure that your server is not the source of the problem.

    Take care,
    - Mark
  • xdm
    xdm La Coruña, Spain
    Hi Enrico

    I read your code and seems that you aren't using any method to manage concurrence in your DatabaseI implementation, this can cause a lot of problems.


    IceUtil provide same class to manage threads and concurrency in c++ , read the chapter 29 Threads and concurrency with c++
  • Thank you Mes and thank you Jose,

    we have decided to simplify the problem, exposing only one component, which uses normal c++ classes instead of too many components (i.e. one adapter and one communicator).

    In this way, we have focused our efforts on controlling the behaviour of exposed operations (including concurrency problems). We are going to implement more parameters for each operation and to modify our "fake" PHP classes, but it seems the right way, isn't it?

    Best regards,
    Enrico & co.
  • xdm
    xdm La Coruña, Spain
    It's not clear to me what you trying to do.

    I think that your problem is that multiple apache threads access to your Ice Servants and this servants aren't handling concurrence. You can configure your web server to use only one threads and view if problem persist.


    Using one or multiple components must not be a problem

    i have and application similar to yours and use only one method to send request to components

    slice interface
    interface WebApplicationManager
    {			
    	WebResponse processRequest(WebRequest request);
    };
    

    c++ implementation
    Oz::Web::WebResponse 
    Oz::Web::WebApplicationManagerI::processRequest(
    	const Oz::Web::WebRequest& request,
    	const Ice::Current& current)
    {
            //First block this object  for read / write
    	IceUtil::RWRecMutex::WLock sync(*this);
            //here write your code
    }
    

    note: to use the previous mutex your class implementation must extend IceUtil::AbstractMutexReadI<IceUtil::RWRecMutex>
  • bernard
    bernard Jupiter, FL
    xdm wrote:
    note: to use the previous mutex your class implementation must extend IceUtil::AbstractMutexReadI<IceUtil::RWRecMutex>

    The various AbstractMutexXXX template classes are useful mainly/only when using the Freeze Evictor. These templates adapt various Mutex classes to an AbstractMutex. Each time the Freeze Evictor streams the state of a managed servant, it locks this servant through this AbstractMutex interface.

    Cheers,
    Bernard