2012-05-14 27 views
8

Tôi đang xây dựng một ứng dụng web Wicket vốn sẽ phải xử lý nhiều yêu cầu đồng thời. Tôi đã thiết lập một môi trường thử nghiệm và một số kịch bản lệnh jmeter để thực hiện kiểm tra tải và tôi nhận thấy rằng tôi có thể làm giảm CPU và bộ nhớ của ứng dụng của mình nếu tôi làm cho hầu hết các trang không có trạng thái.Làm cách nào để tôi có thể tạo trạng thái "AjaxLink" của Wicket?

Tôi đã thêm mã vào phương thức onBeforeRender() của trang lớn nhất để cho tôi biết thành phần nào đang khiến trang của tôi trở nên có trạng thái. Đây là mã tôi có để phát hiện rằng:

@Override 
protected void onBeforeRender() {  
    if (!getSession().isTemporary()) { 
     visitChildren(Component.class, new IVisitor<Component>() { 
      @Override 
      public Object component(Component component) { 
       String pageClassName = AbstractStatelessBasePage.this.getClass().getName(); 
       if (!component.isStateless()) { 

        String msg = pageClassName+" is stateful because of stateful component " + component.getClass().getName() + " with id " + component.getId() + "."; 

        List<IBehavior> behaviourList = component.getBehaviors(); 
        for (IBehavior iBehavior : behaviourList) { 
         if (!iBehavior.getStatelessHint(component)) { 
          msg += "\n\t" + "The component has stateful behaviour: " + iBehavior.getClass().getName(); 
         } 
        } 
        LOG.error(msg); 
       } 

       checkedPages.add(pageClassName); 
       return CONTINUE_TRAVERSAL; 
      } 
     }); 
    } 
} 

Trong đầu ra tôi thấy rằng các hành vi stateful là do AjaxLinks được sử dụng bởi một số thành phần hiện có trong các trang:

ERROR - AbstractStatelessBasePage$1.component(45) | HomePage is stateful because of stateful component InfoGrid$InfoButton with id infoButton. 
    The component has stateful behaviour: org.apache.wicket.ajax.markup.html.AjaxLink$1 

Tôi có đã cố gắng thêm phương thức getStatelessHint() trả về "true" ở một vài nơi, nhưng nó dường như không giúp được gì. Tôi cũng đã kiểm tra mã nguồn Wicket của AjaxLink, các lớp siêu lớp của nó và một số mã xung quanh, nhưng tôi dường như không thể khám phá tại sao AjaxLink cần phải có trạng thái stateful trong mọi trường hợp.

Trong trường hợp của tôi, AjaxLink nằm trong trang không có quốc tịch và liên kết không lưu trữ trạng thái. Làm thế nào tôi có thể làm cho Wicket hiểu rằng AjaxLink này có thể là phi trạng thái?

Nhờ sự giúp đỡ của bạn, Rolf

Edit: Được chấp nhận câu trả lời làm việc với Wicket 1.4.19.

gia tăng như sau để pom.xml maven:

<dependency> 
    <groupId>com.jolira</groupId> 
    <artifactId>wicket-stateless</artifactId> 
    <version>1.0.8</version> 
</dependency> 

Thay đổi tất cả các thành phần trong đó mở rộng "AjaxLink" mở rộng "StatelessAjaxFallbackLink".

Đừng quên thêm dòng sau vào lớp WicketApplication của bạn, nó sẽ giúp bạn tiết kiệm thời gian xử lý sự cố:

@Override 
protected IRequestCycleProcessor newRequestCycleProcessor() { 
    return new StatelessWebRequestCycleProcessor(); 
} 

Xin lưu ý rằng StatelessForm và các công cụ khác không quốc tịch không hoạt động từ bên trong một repeater (như " ListView ") vì một lý do nào đó.

Trả lời

10

Trang trở nên nhà nước khi bạn thêm một hành vi Ajax vào nó (AjaxLink sử dụng AjaxEventBehavior). Điều này là do khi bạn nhấp vào một liên kết Wicket cố gắng tìm cá thể trang tại máy chủ, sau đó tìm thành phần liên kết bên trong nó và cuối cùng thực thi phương thức gọi lại của nó - ví dụ: trong một cái nhấp chuột(). Không lưu trữ trang, không có cách nào để tìm cá thể hành vi ajax và thực thi phương thức gọi lại của nó.

Bạn có thể sử dụng các hành vi và thành phần Ajax của Jolira (https://github.com/jolira/wicket-stateless).Chúng hoạt động hơi khác một chút - khi bạn nhấp vào AjaxLink của Jolira, cuộc gọi Ajax tạo ra một thể hiện hoàn toàn mới của trang, tìm StatelessAjaxLink mới được tạo ra, thực thi phương thức gọi lại của nó, cuối cùng sử dụng AjaxRequestTarget để thêm các thành phần/javascript cho phản hồi Ajax và loại bỏ thể hiện trang mới được tạo ra (nó là rác được thu thập). Yêu cầu Ajax tiếp theo thực hiện tương tự với một thể hiện trang hoàn toàn mới.

Người ta sẽ hỏi "Tại sao mã của Jolira không nằm trong lõi Wicket?" - bởi vì nó cho một phần giải pháp. Ví dụ: nhấp vào statelessAjaxLink1 tạo một Trang mới, thực thi onClick() trên cá thể mới của StatelessAjaxLink trong đó PanelA được thay thế bằng PanelB và thêm bảng điều khiển này (PanelB) vào AjaxRequestTarget. Tóm lại: nhấp vào liên kết này sẽ thay thế phần thân của bảng điều khiển trong trang. Nếu PanelB có một StatelessAjaxLink2 bên trong chính nó thì liên kết này là không thể. Tại sao ? Bởi vì việc kích vào nó sẽ tạo ra một cá thể mới của Trang và cá thể mới này sẽ có PanelA, chứ không phải PanelB, và do đó không có cách nào để tìm StatelessAjaxLink2 để thực thi phương thức onClick() của nó.

Nếu kịch bản của bạn đủ đơn giản và các thành phần của Jolira bao gồm các trường hợp của bạn thì hãy sử dụng chúng. Chỉ cần lưu ý rằng kịch bản phức tạp hơn có thể thất bại.

+0

Tôi thực sự làm bảng thay thế, nhưng tôi đăng ký trong phiên, vì vậy khi instantiating trang tôi có thể nhanh chóng chính xác "thay thế" tấm. Điều này chuyển trạng thái từ trang này sang phiên khác. – Rolf

+0

StatelessAjaxFallbackLink của Jolira đã giải quyết được vấn đề tôi đã nêu trong câu hỏi ban đầu của tôi. Ngay bây giờ tôi đang gặp phải vấn đề với Stateless bên trong lặp, nơi Wicket không thể tìm ra những thành phần để nhắm mục tiêu. Điều này có thể dẫn đến một câu hỏi mới :-) – Rolf

+0

Có điều gì cho Wicket 6.10 không? –

3

Có mã cho số AjaxFallbackLink không quốc tịch được tham chiếu trên wicket wiki và dự án github liên quan mà bạn có thể truy cập các liên kết sau từ đó. Không chắc chắn điều này sẽ hoàn toàn giải quyết vấn đề của bạn, nhưng nó có thể ít nhất là hướng dẫn.

Một phương pháp tương tự đã được thử cho wicket 6, nhưng tác giả cảnh báo nó là thử nghiệm. Mã số là here. Tôi đã không cố gắng sử dụng nó và do đó không thể xác minh cho nó.

+0

Có điều gì cho Wicket 6.10 không? –

+0

@Hendy Irawan - Xem cập nhật của tôi! –

Các vấn đề liên quan