2011-12-13 2 views
2

Java EE에 대한 지식이 많지 않지만 현재 학습 중입니다.Java EE WebApp + icefaces에서 장기 실행 태스크

I는 사용자에 의해 호출 (몇 분까지) 장기 실행 작업을 포함하는 프로젝트를 마련했습니다. 작업은 여러 단계로 구성됩니다. 물론 사용자에게 진행 상황을 보여주고 싶습니다.

이 프로젝트는 JPA, JSF와 Icefaces 자바 EE를 사용합니다. 그것은 Glassfish에서 실행됩니다.

  1. 각 단계 -에서
  2. 후 응답 객체 지속 요청 응답 객체를 생성하고 처리하는 무, 비동기 EJB 생성 :

    는 경험 동료 내게 다음 패턴 adviced 콩, 쿼리를 백업하고 응답이 잘 작동

개체를 표시합니다. 내 유일한 문제는 진행 상황을 반영하도록 상태 사이트를 업데이트하는 것입니다. 현재 x 초마다 간단한 자바 스크립트 페이지를 다시로드하면됩니다.

당신이 JSF 백업 콩에 무 EJB에서 현재 단계를 반영 할 수있는 방법/패턴을 알고 계십니까? 아니면, 나는 x 초마다 backing bean의 값을 쿼리하는 방법을 알고 있는가?

편집 :

내가 메커니즘을 밀어 Icefaces 알고있다,하지만 난 상태 업데이트 사이트는 다음과 같은 이유로 계산 EJB에서 분리되고 싶지 :

  • 백킹 빈은 수 사용자가 사이트를 떠나 나중에 결과를 가져 오기 위해 다시 돌아 왔기 때문에 이미 파괴되었습니다.
  • 여러 세션이 있으므로 한 사용자에 대해 여러 콩이 존재할 수 있습니다.
  • 깨끗한 디자인

답변

1

이 정보를 다시 전달하는 몇 가지 옵션이 있습니다. EJB가 동일한 JVM에 있다면, 특정 싱글 키 맵을 사용하고 특정 키 (세션 ID) 아래에 진행 상황을 저장할 수 있습니다.

그렇지 않은 경우 일부 공유 상태 또는 작업이 필요할 것입니다. 두 계층에서 데이터베이스에

  • 저장을 액세스 할 수있는 몇 가지 옵션이 있습니다 (SQL, JNDI는, LDAP - 더 나은 솔루션 레디 스 같은 키 - 값 저장소가 될 것입니다 - 당신이 그것을 가지고있는 경우)
  • 은 입금 일부 메시징을 사용 웹 티어 측 처리의 상태는이 상태를

선택을 rtrieve 다른 SLSB 방법을 제공하는 것은 쉬운 EJB 계층 측 해시 그것에

  • 상태를 저장하고,하지
  • - 이러한 솔루션을 모두 다른 방법 빨아 .

    0

    얼음 표면을 사용하는 경우 업데이트 렌더링에 ICEpush 메커니즘을 사용할 수 있습니다.

    +0

    당연히,하지만 불행히도 나는 진행 상황을 뒷받침 빈을 알리는 메커니즘을 알지 못합니다. 백킹 빈도 이미 파괴되었을 수 있으며 계산이 끝나면 나중에 다시 돌아올 수 있습니다. 캡슐화로 인해 EJB에 빙판 코드가 필요하지 않습니다. – Michael

    0

    이 작업은 ProgressBar 구성 요소와 함께 스레드 폴링 모델을 사용하여 수행했습니다.

    public void init() 
    { 
        // This method is called by the constructor. 
        // It doesn't matter where you define the PortableRenderer, as long as it's before it's used. 
        PushRenderer.addCurrentSession("fullFormGroup"); 
        portableRenderer = PushRenderer.getPortableRenderer(); 
    } 
    
    
    public void someBeanMethod(ActionEvent evt) 
    { 
        // This is a backing bean method called by some UI event (e.g. clicking a button) 
        // Since it is part of a JSF/HTTP request, you cannot call portableRenderer.render 
    
        copyExecuting = true; 
    
        // Create a status thread and start it 
    
        Thread statusThread = new Thread(new Runnable() { 
         public void run() { 
         try { 
             // message and progress are both linked to components, which change on a portableRenderer.render("fullFormGroup") call 
          message = "Copying..."; 
          // initiates render. Note that this cannot be called from a thread which is already part of an HTTP request 
          portableRenderer.render("fullFormGroup"); 
          do { 
           progress = getProgress(); 
           portableRenderer.render("fullFormGroup"); // render the updated progress 
           Thread.sleep(5000); // sleep for a while until it's time to poll again 
          } while (copyExecuting); 
          progress = getProgress(); 
          message = "Finished!"; 
          portableRenderer.render("fullFormGroup"); // push a render one last time 
         } catch (InterruptedException e) { 
          System.out.println("Child interrupted."); 
         } 
        }); 
        statusThread.start(); 
    
        // create a thread which initiates script and triggers the termination of statusThread 
        Thread copyThread = new Thread(new Runnable() {   
         public void run() { 
         File someBigFile = new File("/tmp/foobar/large_file.tar.gz"); 
          scriptResult = copyFile(someBigFile); // this will take a long time, which is why we spawn a new thread 
          copyExecuting = false; // this will caue the statusThread's do..while loop to terminate 
    
    
         } 
        }); 
        copyThread.start(); 
    }