Re: sfStart() timeout

Steve Loughran <[email protected]> Tue, 28 Nov 2006 11:40:47 +0000
Newsgroups gmane.comp.java.smartfrog.user,gmane.comp.java.smartfrog.devel
Message-ID <[email protected]>
Dominik Pospisil wrote:
> Hello there!
> 
> I am trying to write a smartfrog component which's start can take ralativelly 
> long time (even minutes). The problem is following. Should I run component 
> startup in a new thread and exit sfStart() immidiatelly or should I block 
> sfStart() until component starts up?
> 
> According to docs, when a compoent leave sfStart(), SF assumes that component 
> is running and ready. But If I block sfStart() until component is ready, I 
> receive liveness check errors.
> 
> If I do not block sfStart(), dependant components will fail to start, because 
> component is not ready yet.
> 
> Did I missed something? Is there another solution than increasing liveness 
> checking period?
> 


My recommendation would be to start the work in a separate thread, and 
respond fairly quickly. This means that smartfrog can move everything 
into the started state fairly rapidly.

However, your component's liveness checking code needs to be designed to 
respond to a liveness check while the system is still coming up and not 
fail.

It leaves the problem of how do you block other parts of the system 
until what you are starting comes up. Which, in the case of something 
big like a Xen linux image with a database on top can take a while.

What I've done with that in the past is add new components whose role is 
to block waiting for the visible state of something to change. For 
example, there is a WaitForPage component in the www module that deploys 
a thread that waits for a web page to be readable with an error code in 
range; it will terminate when the page is successfully retrieved. You 
can then use a workflow where you have a sequence of things that block 
until the blocking component is ready.


system extends Parallel {

       appserver extends JBossJVM {
       }


       deployment extends Sequence {
         probe extends SpinUntilHappy {
         }

        tests extends Junit {
          ...
        }
      }

}


What I havent done yet is factor out the test, to have a specific 
Condition interface that anything can implement to be a condition; we 
could have different components to act on these (if/while/waitfor, etc). 
This would tie in well with what I am implementing w.r.t test 
components. I have a (very unstable) test compound whose aim is to 
deploy something, run some tests and then clean up. This stuff is very 
raw right now, as I'm just starting to use it to test the JDBC components:

TableManipulationTest extends TestCompound {

     action extends Compound {
         db extends TestDB;
     }

     tests extends Sequence {

         -- extends CreateUser {
           database LAZY action:db;
           username "newuser";
           password "secret";
         }

         -- extends CreateEventsTable {
           database LAZY action:db;
         }

         -- extends SelectionWorkflow {
           database LAZY action:db;
           sqlCommands [
             "SELECT * from events"
             ];
         }

         -- extends DropTable {
             database LAZY action:db;
             table "events";
         }
     }
   }

Here it deploys the action; once that is started it runs the tests.  For 
that to work against a slow-to-start system I need to block until the 
database is up. While I could put a Block-until-socket-ready component 
into the sequence, having a separate Condition clause would be good as 
the test results would be more meaningful. The test run could look more 
like :




TableManipulationTest extends TestCompound {

     deployTimeout 60000;
     probeTimeout 60000;

     action extends Compound {
         db extends TestDB;
     }

     probe extends SocketOpen {
       port action:db:port;
     }

     tests extends Sequence {

         -- extends CreateUser {
           database LAZY action:db;
           username "newuser";
           password "secret";
         }

         -- extends CreateEventsTable {
           database LAZY action:db;
         }

         -- extends SelectionWorkflow {
           database LAZY action:db;
           sqlCommands [
             "SELECT * from events"
             ];
         }

         -- extends DropTable {
             database LAZY action:db;
             table "events";
         }
     }
   }


I'd then have the test compound would block until the probe was happy or 
a timeout kicked in.

what do you (and the others) think?

-steve



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV