예제 #1
0
파일: edge.cpp 프로젝트: cuchac/gcfs
  saga::task edge::work_start (void)
  {
    if     ( state_ == Stopped ) return task_;
    assert ( state_ == Pending );

    util::scoped_lock (mtx_);

    // we have work to do...
    state_ = Running;

    // lets see if we actually need to do anything
    try 
    {
      saga::filesystem::file f_tgt (session_, tgt_url_);
      saga::filesystem::file f_src (session_, src_url_);

      if ( f_src.get_size () == f_tgt.get_size () )
      {
        optimize_ = true;
      }
    }
    catch ( const saga::exception & e )
    {
      // well, we need to run the edge operation to see what's missing...
      optimize_ = false;
    }


    if ( optimize_ || is_void_ )
    {
      // fake a noop task, which does nothing: simply returnh the empty
      // Done task...
      task_ = saga::task (saga::task::Done);

      std::cout << " === edge run : " << get_name () 
                << " (" << src_url_ << " -> " << tgt_url_ << ")"
                << " [optimized] - " << task_.get_id () 
                << std::endl;

    }
    else
    {
      saga::filesystem::file f_src (session_, src_url_);

      task_ = f_src.copy <saga::task::Async> (tgt_url_, saga::filesystem::Overwrite
                                                      | saga::filesystem::CreateParents);

      std::cout << " === edge run : " << get_name () 
                << " (" << src_url_ << " -> " << tgt_url_ << ") - "
                << task_.get_id () 
                << std::endl;
    }

    task_valid_ = true;
    return task_;
  }
예제 #2
0
  // thread_work is the workload, i.e. the data copy operation
  void edge::thread_work (void)
  {
    try 
    {
      dag_->log (std::string ("edge run: ")
                + src_url_.get_string () + "->" + tgt_url_.get_string ());

      // dump ();

      dag_->lock ();

      // the local file adaptor is not thread save if operating on the same
      // directory structure

      saga::session session = scheduler_->hook_saga_get_session (dag_);

      saga::filesystem::file f_src (session, src_url_);


      // first check if file exists
      bool exists = false;
      try 
      {
        saga::filesystem::file f_tgt (session, tgt_url_);

        std::cout << " ### edge size: " << get_name_s () << " : " << f_tgt.get_size () 
                  << "\t (" << src_url_.get_path () << ")" << std::endl;

        if ( f_tgt.get_size () == f_src.get_size () )
        {
          exists = true;
        }
      }
      catch ( ... )
      {
        // does not exist
      }

      if ( ! exists )
      {
        f_src.copy (tgt_url_, saga::filesystem::Overwrite
                    | saga::filesystem::CreateParents);
      }

      dag_->unlock ();
    }
    catch ( const saga::exception & e ) 
    {
      dag_->unlock ();

      // FIXME: the local adaptor is not doing nicely in multithreaded
      // environments.  Thus, we ignore all errors for now, and rely on the
      // ability of the nodes to flag any missing data files.
#if  1
      dag_->log (std::string ("edge failed to copy data ")
                + src_url_.get_string () + "->" + tgt_url_.get_string () + "\n" 
                + e.what ());

      {
        state_ = Failed;
      }

      // ### scheduler hook
      scheduler_->hook_edge_run_fail (dag_, this);

      return;
#else

      state_ = Done;

      // ### scheduler hook
      scheduler_->hook_edge_run_done (dag_, this);
#endif
    }

    // if we are done copying data, we fire the dependend node
    // this fire may succeed or not - that depends on the availability
    // of _other_ input data to that node.  Only if all data are Done,
    // the fire will actually do anything.  Thus, only the last fire
    // called on a node (i.e. called from its last Pending Edge) will
    // result in a Running node.
    
    {
      if ( state_ != Stopped )
      {
        // done
        state_ = Done;

        // fire dependent node
        tgt_node_->fire ();
      }
    }

    // ### scheduler hook
    scheduler_->hook_edge_run_done (dag_, this);

    return;
  }