X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/hpcvm.git/blobdiff_plain/d83793da6e881ebab006a50a47fbba914e65f9cf..7a473b4f506b5264586f090f34b21fe11531bb70:/src/and/hpcvm/Server.java diff --git a/src/and/hpcvm/Server.java b/src/and/hpcvm/Server.java index 0c696a4..90a8653 100644 --- a/src/and/hpcvm/Server.java +++ b/src/and/hpcvm/Server.java @@ -11,6 +11,7 @@ import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; import java.util.Iterator; +import java.util.concurrent.Semaphore; public class Server extends UnicastRemoteObject implements ServicesServer @@ -31,119 +32,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer } protected int getNb() { return nb ; } - } - - - private class ConnectedClient - { - private ServicesClient stub ; - private int timeout ; - private Status state ; - private String ip ; - private String name ; - private ComputingClient cl ; - - ConnectedClient( ServicesClient _stub ) - { - stub = _stub ; - timeout = 0 ; - state = new Status() ; - state.setStatus( "connected" ) ; - try { - ip = stub.getIPHost() ; - name = stub.getName() ; - } catch (RemoteException e) { - e.printStackTrace(); - } - cl = null ; - } - - protected ServicesClient getStub() { return stub ; } - - protected void setStub( ServicesClient _stub ) { stub = _stub ; } - - protected int getTimeout() { return timeout ; } - - protected void incTimeout() { timeout++ ; } - - protected void resetTimeout() { timeout = 0 ; } - - protected String getStatus() { return state.getStatus() ; } - - protected void setStatus( String _state ) { state.setStatus( _state ) ; } - - protected String getIP() { return ip ; } - - protected String getName() { return name ; } ; - - protected void setComputingClient( ComputingClient _cl ) { cl = _cl ; } - - protected ComputingClient getComputingClient() { return cl ; } - } - - - private class ComputingClient - { - private ConnectedClient client ; - private boolean save_status ; - private ArrayList save_neighbor ; - private String lastSaveName ; - - ComputingClient( ConnectedClient cl ) - { - client = cl ; - save_status = false ; - save_neighbor = new ArrayList() ; - lastSaveName = "none" ; - } - - protected ConnectedClient getClient() { return client ; } - - protected boolean getSaveStatus(){ return save_status ; } - - protected void setSaveStatus( boolean _status ) { save_status = _status ; } - - protected void setSaveNeighbor( ServicesClient _sn ) - { - if( _sn != null ) - { - if( save_neighbor.size() == 0 ) - { - save_neighbor.add( _sn ) ; - } else { - save_neighbor.set( 0, _sn ) ; - } - -// System.out.println( "My save neighbor is " + _sn ) ; - - try { - client.getStub().setSavingNeighbor( _sn ) ; - } catch( RemoteException e ) { - System.err.println( "Error while setting save neighbor on " + - client.getName() + "(" + client.getIP() + ")!" ) ; - e.printStackTrace() ; - } - } - } - - protected ServicesClient getSaveNeighbor() - { - if( save_neighbor.isEmpty() ) - { - return null ; - } else { - return save_neighbor.get( 0 ) ; - } - } - - public void setLastSave( String _saveName ) - { - lastSaveName = _saveName ; - } - - public String getLastSave() { return lastSaveName ; } - - } + } private class IPAssociation @@ -153,8 +42,8 @@ public class Server extends UnicastRemoteObject implements ServicesServer IPAssociation() { - vmIP = null ; - hostIP = null ; + vmIP = "" ; + hostIP = "" ; } protected void setVmIP( String _vmIP ) @@ -184,11 +73,20 @@ public class Server extends UnicastRemoteObject implements ServicesServer private int port ; private ArrayList clients ; private ArrayList computingClients ; + private ArrayList applications ; private int max_timeout ; private ConnectedMonitor monitor ; private DiscCount counter ; private ArrayList vmIPs ; private String working_directory ; + private long save_interleave ; + private Semaphore semaSave ; + private OperatingClients startingClients ; + private OperatingClients deployingClients ; + private LimitThread limitThread ; + private int maxThread ; + private int ind ; + private boolean running ; protected Server() throws RemoteException @@ -196,56 +94,64 @@ public class Server extends UnicastRemoteObject implements ServicesServer super() ; } - + + public void setSaveTime( int _saveTime ) + { + save_interleave = _saveTime * 60 * 1000 ; + } + @Override public Integer register( ServicesClient _stub ) { if( _stub != null ) { - String ip = "" ; - try { - ip = _stub.getIPHost() ; - } catch (RemoteException e) { - e.printStackTrace() ; - return 1 ; - } - - boolean exists = false ; - int i ; - - for( i = 0 ; i < clients.size() ; i++ ) + synchronized( clients ) { - if( ip.equals( clients.get( i ).getIP() ) ) + String ip = "" ; + try { + ip = _stub.getIPHost() ; + } catch (RemoteException e) { + e.printStackTrace() ; + return 1 ; + } + + boolean exists = false ; + int i ; + + for( i = 0 ; i < clients.size() ; i++ ) { - exists = true ; - System.out.println( "Client already connected!" ) ; - break ; + if( ip.equals( clients.get( i ).getIP() ) ) + { + exists = true ; + System.out.println( "Client already connected!" ) ; + break ; + } } - } - - if( exists ) - { - System.out.println( "The client stub will be replaced." ) ; - clients.get( i ).setStub( _stub ) ; - System.out.println( "(reconnection of " + clients.get( i ).getName() + ")" ) ; - return 2 ; - } else { - System.out.println( "New connection!" ) ; - clients.add( new ConnectedClient( _stub ) ) ; - System.out.println( "(connection of " + clients.get( clients.size() - 1 ).getName() + ")" ) ; - generateVmIP( ip ) ; - - if( clients.size() == 0 ) + + if( exists ) { - System.out.println( "There is no client connected." ) ; - } else if( clients.size() == 1 ) { - System.out.println( "There is one client connected." ) ; + System.out.println( "The client stub will be replaced." ) ; + clients.get( i ).setStub( _stub ) ; + System.out.println( "(reconnection of " + clients.get( i ).getName() + ")" ) ; + return 2 ; } else { - System.out.println( "There are " + clients.size() + " clients connected." ) ; - } + System.out.println( "New connection!" ) ; + clients.add( new ConnectedClient( _stub ) ) ; + System.out.println( "(connection of " + clients.get( clients.size() - 1 ).getName() + ")" ) ; + generateVmIP( ip ) ; - return 0 ; + if( clients.size() == 0 ) + { + System.out.println( "There is no client connected." ) ; + } else if( clients.size() == 1 ) { + System.out.println( "There is one client connected." ) ; + } else { + System.out.println( "There are " + clients.size() + " clients connected." ) ; + } + + return 0 ; + } } } @@ -259,7 +165,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer { for( int i = 0 ; i < vmIPs.size() ; i++ ) { - if( vmIPs.get( i ).getHostIP() == null ) + if( vmIPs.get( i ).getHostIP().equalsIgnoreCase( "" ) ) { vmIPs.get( i ).setHostIP( _ip ) ; @@ -295,9 +201,10 @@ public class Server extends UnicastRemoteObject implements ServicesServer for( int i = 0 ; i < clients.size() ; i++ ) { if( _ip.equals( clients.get( i ).getIP() ) ) - { + { clients.get( i ).setStatus( _status ) ; System.out.println( "Client " + clients.get( i ).getName() + " changed its status to: " + _status ) ; + break ; } } @@ -310,12 +217,25 @@ public class Server extends UnicastRemoteObject implements ServicesServer port = _port ; max_timeout = 4 ; - clients = new ArrayList() ; - computingClients = new ArrayList() ; + clients = new ArrayList() ; + computingClients = new ArrayList() ; + applications = new ArrayList() ; monitor = null ; + startingClients = new OperatingClients() ; + deployingClients = new OperatingClients() ; + limitThread = new LimitThread() ; + maxThread = 20 ; + + ind = -1 ; + running = false ; + working_directory = "/localhome/vmware" ; + save_interleave = 30 * 60 * 1000 ; + + semaSave = new Semaphore( 1 ) ; + exportObject() ; vmIPs = new ArrayList() ; @@ -326,12 +246,15 @@ public class Server extends UnicastRemoteObject implements ServicesServer vmIPs.get( vmIPs.size() - 1 ).setVmIP( "10.11.10." + i ) ; } - clients = new ArrayList() ; + clients = new ArrayList() ; counter = new DiscCount() ; monitor = new ConnectedMonitor() ; monitor.start() ; + + // TODO + // Check if there are running applications ... and restart them :) } @@ -342,9 +265,11 @@ public class Server extends UnicastRemoteObject implements ServicesServer for( int i = 0 ; i < clients.size() ; i++ ) { try { + clients.get( i ).getStub().emergencyStop() ; clients.get( i ).getStub().stop() ; } catch (RemoteException e) { - e.printStackTrace(); + System.err.println( "Unable to send stop signal to " + clients.get( i ).getName() ) ; + e.printStackTrace() ; } } @@ -428,6 +353,15 @@ public class Server extends UnicastRemoteObject implements ServicesServer ComputingClient cc = cl.getComputingClient() ; // ServicesClient dead = cc.getClient().getStub() ; String ipDead = cc.getClient().getIP() ; + SaveNeighbor snDead = null ; + for( int i = 0 ; i < computingClients.size() ; i++ ) + { + if( computingClients.get( i ).getSaveNeighbor().getIPHost().equalsIgnoreCase( ipDead ) ) + { + snDead = computingClients.get( i ).getSaveNeighbor() ; + break ; + } + } boolean ok = false ; @@ -458,7 +392,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer ComputingClient ccl = new ComputingClient( clients.get(i) ) ; clients.get( i ).setComputingClient( ccl ) ; - ServicesClient sn = computingClients.get( pos ).getSaveNeighbor() ; + SaveNeighbor sn = computingClients.get( pos ).getSaveNeighbor() ; ccl.setSaveNeighbor( sn ) ; computingClients.set( pos, ccl ) ; @@ -470,39 +404,58 @@ public class Server extends UnicastRemoteObject implements ServicesServer } catch( RemoteException e ) { System.err.println( "Unable to indicate to client to retrieve last save!" ) ; e.printStackTrace() ; + yield() ; } if( res == 0 ) { ok = true ; + + boolean ok_new = false, ok_old = false ; - // replace dead client in vmIPs + // replace dead client in vmIPs for( int j = 0 ; j < vmIPs.size() ; j++ ) { + if( vmIPs.get( j ).getHostIP().equalsIgnoreCase( computingClients.get( pos ).getClient().getIP() ) ) + { + vmIPs.get( j ).setHostIP( "" ) ; + ok_new = true ; + } if( vmIPs.get( j ).getHostIP().equalsIgnoreCase( ipDead ) ) { String vmIP = vmIPs.get( j ).getVmIP() ; vmIPs.get( j ).setHostIP( computingClients.get( pos ).getClient().getIP() ) ; - + ok_old = true ; + try { computingClients.get( pos ).getClient().getStub().setIPVM( vmIP ) ; } catch( RemoteException e ) { System.err.println( "Unable to set the new VM IP on the replacing client!" ) ; e.printStackTrace() ; + yield() ; + } + + if( ok_new && ok_old ) + { + break ; } - break ; } } + + // Replacing in RunningApplication + applications.get( ind ).replaceComputingClient( cc, ccl ) ; + + for( int l = 0 ; l < applications.get( ind ).getComputingClients().size() ; l++ ) + { + applications.get( ind ).getComputingClients().get( l ).setSaveRequest( false ) ; + } + System.out.println( "Successful redeployment of the VM." ) ; } else { System.err.println( "Unable to deploy the save on the new computing client!" ) ; } } -// } else { -// System.err.println( "Problem while launching the VM on " -// + clients.get(i).getName() + "!" ) ; -// } if( ok ) { @@ -510,7 +463,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer { try { computingClients.get( k ).getClient().getStub(). - replaceSavingNeighbor( ipDead, clients.get( i ).getStub() ) ; + replaceSaveNeighbor( snDead, new SaveNeighbor( clients.get( i ).getStub() ) ) ; } catch( RemoteException e ) { System.err.println( "Unable to inform " + computingClients.get( k ).getClient().getName() + " of the replacement of a save neighbor!" ) ; @@ -552,7 +505,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer @Override public void run() { - boolean change ; + boolean change, dead ; while( run ) { @@ -565,49 +518,72 @@ public class Server extends UnicastRemoteObject implements ServicesServer { ConnectedClient cl = it.next() ; cl.incTimeout() ; + dead = false ; - if( cl.getTimeout() > max_timeout ) + if( cl.getTimeout() > max_timeout || cl.getFail() ) { - System.out.println( "Disconnection of " + cl.getName() ) ; - if( cl.getStatus().equalsIgnoreCase( "running" ) || cl.getStatus().equalsIgnoreCase( "saving" ) ) + dead = true ; + if( ! cl.getFail() ) + { + try { + cl.getStub().echo() ; + cl.resetTimeout() ; + dead = false ; + } catch( RemoteException e ) { + dead = true ; + } + } + + if( dead ) { - System.out.println( "A VM was running on it!!" ) ; - System.out.println( "I will redeploy a save and restart all VM ..." ) ; + System.out.println( "Disconnection of " + cl.getName() ) ; + if( cl.getStatus().equalsIgnoreCase( "running" ) || cl.getStatus().equalsIgnoreCase( "saving" ) ) + { + System.out.println( "A VM was running on it!!" ) ; + System.out.println( "I will redeploy a save and restart all VM ..." ) ; -// for( int i = 0 ; i < computingClients.size() ; i++ ) -// { -// if( computingClients.get( i ).getClient().getIP().equals( cl.getIP() ) ) +// for( int i = 0 ; i < computingClients.size() ; i++ ) // { -// computingClients.remove( i ) ; -// break ; +// if( computingClients.get( i ).getClient().getIP().equals( cl.getIP() ) ) +// { +// computingClients.remove( i ) ; +// break ; +// } // } -// } - synchronized( counter ){ - counter.inc() ;} + synchronized( counter ) + { + counter.inc() ; + } - - new Server.FaultManager( cl ).start() ; - nb_disconnections_computing++ ; - } else { - System.out.println( "There was no VM running on it." ) ; - System.out.println( "Maybe it will come back later :)" ) ; - } + new Server.FaultManager( cl ).start() ; + nb_disconnections_computing++ ; + } else { + System.out.println( "There was no VM running on it." ) ; + System.out.println( "Maybe it will come back later :)" ) ; + } - it.remove() ; - nb_disconnections++ ; - change = true ; + synchronized( clients ) + { + it.remove() ; + } + nb_disconnections++ ; + change = true ; + } } } if( change ) { - if( clients.size() == 0 ) + synchronized( clients ) { - System.out.println( "There is no client connected." ) ; - } else if( clients.size() == 1 ) { - System.out.println( "There is one client connected." ) ; - } else { - System.out.println( "There are " + clients.size() + " clients connected." ) ; + if( clients.size() == 0 ) + { + System.out.println( "There is no client connected." ) ; + } else if( clients.size() == 1 ) { + System.out.println( "There is one client connected." ) ; + } else { + System.out.println( "There are " + clients.size() + " clients connected." ) ; + } } } @@ -626,6 +602,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer } catch( RemoteException e ) { System.err.println( "Unable to invoke emergency stop signal on " + clients.get( i ).getName() ) ; e.printStackTrace() ; + yield() ; } } } @@ -645,26 +622,41 @@ public class Server extends UnicastRemoteObject implements ServicesServer counter.wait() ; } catch( InterruptedException e ) { e.printStackTrace() ; + yield() ; } } } - for( int i = 0 ; i < computingClients.size() ; i++ ) + for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ ) { - final ServicesClient sc = computingClients.get( i ).getClient().getStub() ; + applications.get( ind ).getComputingClients().get( i ).setRestartOk( false ) ; - new Thread( new Runnable() { - - @Override - public void run() - { - try { - sc.restartVMAfterCrash() ; - } catch( RemoteException e ) { - e.printStackTrace() ; - } - } - } ).start() ; + new RestartVM( applications.get( ind ).getComputingClients().get( i ).getClient() ).start() ; + +// final ServicesClient sc = applications.get( ind ).getComputingClients().get( i ).getClient().getStub() ; + +// new Thread( new Runnable() { +// +// @Override +// public void run() +// { +// try { +// if( sc.restartVMAfterCrash() != 0 ) +// { +// System.err.println( "Problem while restarting VM on " +sc.getName() + "!" ) ; +// } +// } catch( RemoteException e ) { +// try { +// System.err.println( "Problem while restarting VM on " + sc.getName() + "!" ) ; +// } catch( RemoteException e1 ) { +// System.err.println( "Problem while restarting a VM!" ) ; +// e1.printStackTrace() ; +// } +// e.printStackTrace() ; +// yield() ; +// } +// } +// } ).start() ; } } @@ -673,6 +665,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer Thread.sleep( 2000 ) ; } catch( InterruptedException e ) { e.printStackTrace() ; + yield() ; } } } @@ -709,10 +702,13 @@ public class Server extends UnicastRemoteObject implements ServicesServer try { computingClients.get( i ).getClient().getStub().saveOk() ; } catch (RemoteException e) { - e.printStackTrace(); + System.err.println( "Unable to invoke the saveOk method on " + computingClients.get( i ).getClient().getName() ) ; + e.printStackTrace() ; } computingClients.get( i ).setSaveStatus( false ) ; } + + applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ; } return 0 ; @@ -728,49 +724,118 @@ public class Server extends UnicastRemoteObject implements ServicesServer if( computingClients.get( i ).getClient().getIP().equalsIgnoreCase( _ip ) ) { computingClients.get( i ).setLastSave( _saveName ) ; - System.out.println( "Save name successfully change for " + _ip ) ; + System.out.println( "Save name successfully changed on " + computingClients.get( i ).getClient().getName() ) ; return 0 ; } } + + System.err.println( "Unable to found computing client with IP " + _ip + "!" ) ; + return 1 ; } + System.err.println( "Unable to change save name. IP or save name empty ! (IP: " + _ip + " ; save name: " + _saveName +")" ) ; + return 1 ; } + @Override public ArrayList startApplication( int _nb ) { int nb = clients.size() - computingClients.size() ; - if( nb > _nb ) + if( nb > _nb && ! running ) { - ArrayList ac = new ArrayList() ; - ArrayList tmp = new ArrayList() ; + running = true ; + + final ArrayList ac = new ArrayList() ; + final ArrayList tmp = new ArrayList() ; + + RunningApplication app = new RunningApplication( "Test" ) ; int i = 0 ; + boolean ok ; while( i < clients.size() && ac.size() < _nb ) { - if( clients.get(i).getStatus().equalsIgnoreCase( "connected" ) ) + ok = false ; + if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) ) { - int res = 1 ; - try { - res = clients.get( i ).getStub().startVM( 0 ) ; - } catch( RemoteException e ) { - e.printStackTrace(); + synchronized( startingClients ) + { + while( ac.size() + startingClients.getNb() >= _nb ) + { + if( ac.size() == _nb ) break ; + + try { + startingClients.wait() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + } + + if( ac.size() < _nb ) + { + startingClients.inc() ; + ok = true ; + } } - if( res == 0 ) + if( ok ) { - ac.add( clients.get( i ).getStub() ) ; - clients.get( i ).setStatus( "running" ) ; - ComputingClient cl = new ComputingClient( clients.get( i ) ) ; - clients.get( i ).setComputingClient( cl ) ; - computingClients.add( cl ) ; - tmp.add( cl ) ; - } else { - System.err.println( "Problem while launching the VM on " - + clients.get(i).getName() + "!" ) ; + synchronized( limitThread ) + { + while( limitThread.getNb() >= maxThread ) + { + try { + limitThread.wait() ; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + limitThread.inc() ; + } + + final int indice = i ; + new Thread( new Runnable() + { + @Override + public void run() + { + int res = 1 ; + try { + res = clients.get( indice ).getStub().startVM( 0 ) ; + } catch( RemoteException e ) { + e.printStackTrace() ; + } + + if( res == 0 ) + { + ac.add( clients.get( indice ).getStub() ) ; + clients.get( indice ).setStatus( "running" ) ; + ComputingClient cl = new ComputingClient( clients.get( indice ) ) ; + clients.get( indice ).setComputingClient( cl ) ; + computingClients.add( cl ) ; + tmp.add( cl ) ; + } else { + System.err.println( "Problem while launching the VM on " + + clients.get( indice ).getName() + "!" ) ; + } + + synchronized( limitThread ) + { + limitThread.dec() ; + limitThread.notifyAll() ; + } + + synchronized( startingClients ) + { + startingClients.dec() ; + startingClients.notifyAll() ; + } + } + }).start() ; } } @@ -779,6 +844,10 @@ public class Server extends UnicastRemoteObject implements ServicesServer if( ac.size() == _nb ) { + app.setComputingClients( tmp ) ; + app.setRunning( true ) ; + app.setStartTime( System.currentTimeMillis() ) ; + int index, index2 ; /* Choosing save neighbors */ for( i = 0 ; i < tmp.size() ; i++ ) @@ -792,7 +861,12 @@ public class Server extends UnicastRemoteObject implements ServicesServer { System.err.println( "Problem in ComputingClients list!" ) ; } else { - computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getStub() ) ; + try { + computingClients.get( index ).setSaveNeighbor( new SaveNeighbor( computingClients.get( index2 ).getClient().getStub() )) ; + } catch( RemoteException e ) { + System.err.println( "Unable to create the save neighbor!" ) ; + e.printStackTrace() ; + } } } else { index = computingClients.indexOf( tmp.get( i ) ) ; @@ -802,45 +876,239 @@ public class Server extends UnicastRemoteObject implements ServicesServer { System.err.println( "Problem in ComputingClients list!" ) ; } else { - computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getStub() ) ; + try { + computingClients.get( index ).setSaveNeighbor( new SaveNeighbor( computingClients.get( index2 ).getClient().getStub() ) ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to create the save neighbor!" ) ; + e.printStackTrace() ; + } } } } } - /* Cleaning */ - tmp.clear() ; - tmp = null ; + applications.add( app ) ; + + ind = applications.indexOf( app ) ; return ac ; } return null ; } + + + @Override + public void requestSave( String _ip ) + { + try { + semaSave.acquire() ; + } catch( InterruptedException e ) { + System.err.println( "Unable to obtain the semaphore for semaSave!" ) ; + e.printStackTrace() ; + } + + final String ip = _ip ; + + new Thread( new Runnable() { + + @Override + public void run() + { + treatRequestSave( ip ) ; + } + } ).start() ; + } - + + public void treatRequestSave( String _ip ) + { + if( applications.size() > 0 && _ip != null && _ip.length() > 0 ) + { + if( (System.currentTimeMillis() - applications.get( ind ).getLastSaveDate()) > save_interleave ) + { + // Mark it as a requester + for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ ) + { + if( applications.get( ind ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) ) + { + applications.get( ind ).getComputingClients().get( i ).setSaveRequest( true ) ; + + break ; + } + } + + semaSave.release() ; + + // Is every body ok? + boolean ok = false ; + for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ ) + { + if( i == 0 ) + { + ok = applications.get( ind ).getComputingClients().get( i ).getSaveRequest() ; + } else { + ok = ok & applications.get( ind ).getComputingClients().get( i ).getSaveRequest() ; + } + + if( ! ok ) + { + break ; + } + } + + if( ok ) + { +// try { +// Thread.sleep( 5000 ) ; +// } catch( InterruptedException e1 ) { +// e1.printStackTrace() ; +// } + + for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ ) + { + try { + applications.get( ind ).getComputingClients().get( i ).getClient().getStub().responseSave( true ) ; + applications.get( ind ).getComputingClients().get( i ).setSaveRequest( false ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to send the save request response to " + + applications.get( ind ).getComputingClients().get( i ).getClient().getName() + "!" ) ; + e.printStackTrace() ; + } + } + + applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ; + } + + } else { + semaSave.release() ; + + for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ ) + { + if( applications.get( ind ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) ) + { + try { + applications.get( ind ).getComputingClients().get( i ).getClient().getStub().responseSave( false ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to send the save request response to " + + applications.get( ind ).getComputingClients().get( i ).getClient().getName() + "!" ) ; + e.printStackTrace() ; + } + break ; + } + } + } + } else { + semaSave.release() ; + System.err.println( "!! Serious problem in treatRequestSave method!!" ) ; + } + } + + + @Override + public void restartOk( String _ip ) + { + if( applications.size() > 0 && _ip != null && _ip.length() > 0 ) + { + System.out.println( "Client " + _ip + " has finished to restart ("+applications.get( ind ).getComputingClients().size()+") ... " ) ; +// if( (System.currentTimeMillis() - applications.get( ind ).getLastSaveDate()) > save_interleave ) + { + // Has it already finished? + for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ ) + { + if( applications.get( ind ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) ) + { + applications.get( ind ).getComputingClients().get( i ).setRestartOk( true ) ; + + break ; + } + } + + // Is everybody ok? + boolean ok = false ; + for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ ) + { + if( i == 0 ) + { + ok = applications.get( ind ).getComputingClients().get( i ).getRestartOk() ; + } else { + ok = ok & applications.get( ind ).getComputingClients().get( i ).getRestartOk() ; + } + + if( ! ok ) + { + break ; + } + } + + if( ok ) + { + applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ; + + for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ ) + { + applications.get( ind ).getComputingClients().get( i ).setRestartOk( false ) ; + } + } + + } + } + } + + + @Override + public void goApplication() + { + synchronized( applications ) { + if( running && ! applications.get( ind ).getStartMark() ) + { + System.out.println( "Application is starting." ) ; + applications.get( ind ).setStartMark() ; + applications.get( ind ).setStartTime( System.currentTimeMillis() ) ; + applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ; + } + } + } + @Override public void endApplication() { - Iterator it = computingClients.iterator() ; - - while( it.hasNext() ) + synchronized( applications ) { - ComputingClient cl = it.next() ; + if( running ) + { + applications.get( ind ).setEndTime( System.currentTimeMillis() ) ; + applications.get( ind ).setRunning( false ) ; + applications.get( ind ).clear() ; + + Iterator it = computingClients.iterator() ; + + while( it.hasNext() ) + { + ComputingClient cl = it.next() ; - try { - cl.getClient().getStub().stopVM() ; - } catch (RemoteException e) { - e.printStackTrace(); - } + try { + cl.getClient().getStub().emergencyStop() ; + } catch (RemoteException e) { + e.printStackTrace(); + } - cl.getClient().setStatus( "connected" ) ; - cl.getClient().setComputingClient( null ) ; - it.remove() ; - cl = null ; - } + cl.getClient().setStatus( "connected" ) ; + cl.getClient().setComputingClient( null ) ; + it.remove() ; + cl = null ; + } + + applications.get( ind ).clear() ; + + running = false ; + + System.out.println( "Application " + applications.get( ind ).getName() + " ends in " + + applications.get( ind ).getExecutionTime() + " seconds." ) ; + } + } } @@ -863,10 +1131,9 @@ public class Server extends UnicastRemoteObject implements ServicesServer } - public Integer deployVM( String _name, String _archive, String _directory ) + public Integer deployVM( final String _name, final String _archive, final String _directory ) { - int pb = -1 ; - int nb = 0 ; + int nb = 0, pb = 0 ; if( _name != null && _name.length() > 0 && _archive != null && _name.length() > 0 && _directory != null && _directory.length() > 0 ) @@ -888,113 +1155,161 @@ public class Server extends UnicastRemoteObject implements ServicesServer file = null ; // TODO do a better deployment !! - int ret ; - boolean error ; +// int ret ; +// boolean error, ok, server ; +// ArrayList deployed = new ArrayList() ; - pb = 0 ; +// boolean server = true ; +// boolean ok ; for( int i = 0 ; i < clients.size() ; i++ ) { - ret = 1 ; - error = false ; - try { - ret = clients.get( i ).getStub().deployVM( _name, _archive, _directory ) ; - } catch( RemoteException e ) { - System.err.println( "Unable to deploy the VM on " + clients.get( i ).getName() + "!" ) ; - e.printStackTrace() ; - } - - // The client does not have the archive, we have to send it. - if( ret == 2 ) - { - System.out.print( "Sending VM archive to " + clients.get( i ).getName() + " ... " ) ; +// ret = 1 ; + nb++ ; +// error = false ; +// ok = false ; + if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) ) + { + synchronized( limitThread ) + { + while( limitThread.getNb() >= maxThread ) + { + try { + limitThread.wait() ; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + limitThread.inc() ; + } + + final int indice = i ; + new Thread( new Runnable() { + + @Override + public void run() { + int ret = -1 ; + boolean error = true ; + + try { + ret = clients.get( indice ).getStub().deployVM( _name, _archive, _directory ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to deploy the VM on " + clients.get( indice ).getName() + "!" ) ; + e.printStackTrace() ; + } - String wd = "" ; - String snIP = "" ; - error = false ; + // The client does not have the archive, we have to send it. + if( ret == 2 ) + { + // Attention au multi-envois !!! + System.out.print( "Sending VM archive to " + clients.get( indice ).getName() + " ... " ) ; - try { - wd = clients.get( i ).getStub().getWorkingDirectory() ; - snIP = clients.get( i ).getStub().getIPHost() ; - } catch (RemoteException e2) { - System.err.println( "Unable to retrieve information on " + clients.get( i ).getName() + "!" ) ; - e2.printStackTrace() ; - error = true ; - pb++ ; - } + String wd = "" ; + String snIP = "" ; + error = false ; + + try { + wd = clients.get( indice ).getStub().getWorkingDirectory() ; + snIP = clients.get( indice ).getStub().getIPHost() ; + } catch (RemoteException e2) { + System.err.println( "Unable to retrieve information on " + clients.get( indice ).getName() + "!" ) ; + e2.printStackTrace() ; + error = true ; + } - String[] command = new String[]{ "/usr/bin/scp", working_directory + "/" + _archive, - snIP + ":" + wd } ; + String[] command = new String[]{ "/usr/bin/scp", working_directory + "/" + _archive, + snIP + ":" + wd } ; - if( ! error ) - try { - Process proc = Runtime.getRuntime().exec( command ) ; - proc.waitFor() ; + if( ! error ) + { + try { + Process proc = Runtime.getRuntime().exec( command ) ; + proc.waitFor() ; - if( proc.exitValue() == 0 ) - { - System.out.println( "Initial VM archive successfully sent." ) ; - } else { - System.err.println( "Initial VM archive not sent!" ) ; -// printProcessError( p.getErrorStream() ) ; - System.err.println( "Error: " + proc.exitValue() ) ; - BufferedReader b = new BufferedReader( new InputStreamReader( proc.getErrorStream() ) ) ; + if( proc.exitValue() == 0 ) + { + System.out.println( "Initial VM archive successfully sent." ) ; + } else { + System.err.println( "Initial VM archive not sent!" ) ; + System.err.println( "Error: " + proc.exitValue() ) ; + BufferedReader b = new BufferedReader( new InputStreamReader( proc.getErrorStream() ) ) ; - String l ; - try { - while( (l = b.readLine()) != null ) + String l ; + try { + while( (l = b.readLine()) != null ) + { + System.err.println( l ) ; + } + } catch( IOException e ) { + e.printStackTrace() ; + } + + error = true ; + } + } catch( IOException e ) { + System.err.println( "Error during initial VM archive send command: " ) ; + e.printStackTrace() ; + error = true ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + error = true ; + } + } + + + if( ! error ) + { + // Second try ... + ret = 1 ; + try { + ret = clients.get( indice ).getStub().deployVM( _name, _archive, _directory ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to deploy the VM on " + clients.get( indice ).getName() + "!" ) ; + e.printStackTrace() ; + } + } + } + + if( ret == 0 ) + { + System.out.println( "Initial VM archive successfully deployed on " + clients.get( indice ).getName() + "." ) ; + + synchronized( deployingClients ) { - System.err.println( l ) ; + deployingClients.inc() ; } - } catch( IOException e ) { - e.printStackTrace() ; } - error = true ; - pb++ ; + synchronized( limitThread ) + { + limitThread.dec() ; + limitThread.notifyAll() ; + } } - } catch( IOException e ) { - System.err.println( "Error during initial VM archive send command: " ) ; - e.printStackTrace() ; - error = true ; - pb++ ; - } catch( InterruptedException e ) { - e.printStackTrace() ; - error = true ; - pb++ ; - } - - - if( error ) - { - continue ; - } - - // Second try ... - ret = 1 ; - try { - ret = clients.get( i ).getStub().deployVM( _name, _archive, _directory ) ; - } catch( RemoteException e ) { - System.err.println( "Unable to deploy the VM on " + clients.get( i ).getName() + "!" ) ; - e.printStackTrace() ; - pb++ ; - } + }).start() ; } - - if( ret == 0 ) - { - System.out.println( "Initial VM archive successfully deployed on " + clients.get( i ).getName() + "." ) ; - nb++ ; + } + } + + synchronized( limitThread ) + { + while( limitThread.getNb() > 0 ) + { + try { + limitThread.wait() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; } } } - if( pb > 0 ) + if( nb - deployingClients.getNb() > 0 ) { if( pb == 1 ) System.err.println( "** " + pb + " machine is not deployed!" ) ; if( pb > 1 ) - System.err.println( "** " + pb + " machine(s) are not deployed!" ) ; + System.err.println( "** " + pb + " machines are not deployed!" ) ; } return nb ; @@ -1006,6 +1321,80 @@ public class Server extends UnicastRemoteObject implements ServicesServer return working_directory ; } + + private class OperatingClients + { + private int nb ; + + OperatingClients() { nb = 0 ; } + + protected void inc() { nb++ ; } + + protected void dec() { nb-- ; } + + protected int getNb() { return nb ; } + } + + + private class LimitThread + { + private int nb ; + + LimitThread() { nb = 0 ; } + + protected void inc() { nb++ ; } + + protected void dec() { nb-- ; } + + protected int getNb() { return nb ; } + } + + + private class RestartVM extends Thread + { + private ConnectedClient cc ; + + protected RestartVM( ConnectedClient _cc ) + { + cc = _cc ; + } + + public void run() + { + boolean error = false ; + if( cc != null ) + { + try { + if( cc.getStub().restartVMAfterCrash() != 0 ) + { + System.err.println( "Problem while restarting VM on " + cc.getName() + "!" ) ; + error = true ; + } + } catch( RemoteException e ) { + e.printStackTrace() ; + error = true ; + yield() ; + } + } else { + System.err.println( "The client to restart is null!" ) ; + } + + if( error ) + { + cc.setFail( true ) ; + + try { + System.out.print( "Trying to stop the client ... " ) ; + cc.getStub().stop() ; + System.out.println( "successful client stop." ); + } catch( RemoteException e ) { + System.out.println( "unsuccessful client stop!" ) ; + e.printStackTrace() ; + } + } + } + } + } /** La programmation est un art, respectons ceux qui la pratiquent !! **/