1818
1919import java .text .DateFormat ;
2020import java .util .Date ;
21+ import java .util .HashMap ;
2122import java .util .Iterator ;
2223import java .util .List ;
2324import java .util .Map ;
3233import org .tepi .filtertable .paged .PagedTableChangeEvent ;
3334import org .vaadin .dialogs .ConfirmDialog ;
3435
35- import ru .xpoft .vaadin .VaadinView ;
36-
3736import com .github .wolfie .refresher .Refresher ;
3837import com .vaadin .data .Property ;
3938import com .vaadin .data .util .IndexedContainer ;
4241import com .vaadin .server .Page ;
4342import com .vaadin .server .Resource ;
4443import com .vaadin .server .ThemeResource ;
45- import com .vaadin .ui .* ;
44+ import com .vaadin .ui .Button ;
4645import com .vaadin .ui .Button .ClickEvent ;
4746import com .vaadin .ui .Button .ClickListener ;
47+ import com .vaadin .ui .CustomTable ;
48+ import com .vaadin .ui .Embedded ;
49+ import com .vaadin .ui .HorizontalLayout ;
50+ import com .vaadin .ui .Notification ;
51+ import com .vaadin .ui .UI ;
52+ import com .vaadin .ui .VerticalLayout ;
4853import com .vaadin .ui .Window .CloseEvent ;
4954import com .vaadin .ui .Window .CloseListener ;
5055
6873import cz .cuni .mff .xrg .odcs .frontend .i18n .Messages ;
6974import cz .cuni .mff .xrg .odcs .frontend .navigation .Address ;
7075import cz .cuni .mff .xrg .odcs .frontend .navigation .ParametersHandler ;
76+ import ru .xpoft .vaadin .VaadinView ;
7177
7278/**
7379 * GUI for Scheduler page which opens from the main menu. Contains table with
@@ -147,6 +153,17 @@ public class Scheduler extends ViewComponent implements PostLogoutCleaner, Prese
147153
148154 private boolean isMainLayoutInitialized = false ;
149155
156+ /**
157+ * Pipeline cache for light pipelines loading
158+ */
159+ private Map <Long , Schedule > scheduleCache = new HashMap <>();
160+
161+ private static final int CACHE_MAX_SIZE = 100 ;
162+
163+ private static final int CACHE_TIMEOUT = 300000 ;
164+
165+ private Date lightCacheLastReload = new Date ();
166+
150167 /**
151168 * The constructor should first build the main layout, set the composition
152169 * root and then do any custom initialization.
@@ -170,25 +187,45 @@ public void enter(ViewChangeEvent event) {
170187 }
171188 setCompositionRoot (mainLayout );
172189
173- refreshManager = ((AppEntry ) UI .getCurrent ()).getRefreshManager ();
174- refreshManager .addListener (RefreshManager .SCHEDULER , new Refresher .RefreshListener () {
190+ addRefreshListener ();
191+
192+ setParameters (ParametersHandler .getConfiguration (event .getParameters ()));
193+ }
194+
195+ @ Override
196+ public Object enter () {
197+ if (!isMainLayoutInitialized ) {
198+ buildMainLayout ();
199+ isMainLayoutInitialized = true ;
200+ }
201+ setCompositionRoot (mainLayout );
202+
203+ addRefreshListener ();
204+
205+ return this ;
206+ }
207+
208+ private void addRefreshListener () {
209+ this .refreshManager = ((AppEntry ) UI .getCurrent ()).getRefreshManager ();
210+ this .refreshManager .addListener (RefreshManager .SCHEDULER , new Refresher .RefreshListener () {
175211 private long lastRefreshFinished = 0 ;
176212
177213 @ Override
178214 public void refresh (Refresher source ) {
179215 if (new Date ().getTime () - lastRefreshFinished > RefreshManager .MIN_REFRESH_INTERVAL ) {
180216 boolean hasModifiedExecutions = pipelineFacade .hasModifiedExecutions (lastLoad );
181217 if (hasModifiedExecutions ) {
218+ LOG .debug ("Modified executions found, refreshing ..." );
182219 lastLoad = new Date ();
183220 refreshData ();
221+ LOG .debug ("Scheduler refreshed." );
184222 }
185- LOG . debug ( "Scheduler refreshed." );
223+
186224 lastRefreshFinished = new Date ().getTime ();
187225 }
188226 }
189227 });
190- refreshManager .triggerRefresh ();
191- setParameters (ParametersHandler .getConfiguration (event .getParameters ()));
228+ this .refreshManager .triggerRefresh ();
192229 }
193230
194231 /**
@@ -460,15 +497,17 @@ private static String getScheduledByDisplayName(Schedule schedule) {
460497 /**
461498 * Calls for refresh table {@link #schedulerTable}.
462499 */
500+ @ SuppressWarnings ("deprecation" )
463501 private void refreshData () {
502+ List <Schedule > schedules = this .scheduleFacade .getAllSchedules ();
503+ reloadScheduleCache (schedules );
464504 int page = schedulerTable .getCurrentPage ();
465- tableData = getTableData (scheduleFacade . getAllSchedules () );
505+ tableData = getTableData (schedules );
466506 schedulerTable .setContainerDataSource (tableData );
467507 schedulerTable .setCurrentPage (page );
468508 schedulerTable .setVisibleColumns ((Object []) visibleCols );
469509 schedulerTable .setFilterFieldVisible ("commands" , false );
470510 schedulerTable .setFilterFieldVisible ("duration" , false );
471-
472511 }
473512
474513 /**
@@ -486,13 +525,14 @@ private void showSchedulePipeline(Long id, Long pipelineId) {
486525 @ Override
487526 public void windowClose (CloseEvent e ) {
488527 refreshData ();
528+ addRefreshListener ();
489529 }
490530 });
491531 }
492532
493533 Schedule schedule = null ;
494534 if (id != null ) {
495- schedule = scheduleFacade . getSchedule (id );
535+ schedule = getSchedule (id );
496536 }
497537 schedulePipeline .setSelectedSchedule (schedule );
498538 schedulePipeline .enableComboPipeline ();
@@ -520,7 +560,7 @@ class actionColumnGenerator implements CustomTable.ColumnGenerator {
520560 @ Override
521561 public Object generateCell (final CustomTable source , final Object itemId , Object columnId ) {
522562 final Long schId = Long .parseLong (tableData .getContainerProperty (itemId , "schid" ).getValue ().toString ());
523- Schedule schedule = scheduleFacade . getSchedule (schId );
563+ Schedule schedule = getSchedule (schId );
524564 Property propStatus = source .getItem (itemId ).getItemProperty ("status" );
525565
526566 HorizontalLayout layout = new HorizontalLayout ();
@@ -589,22 +629,22 @@ public void buttonClick(ClickEvent event) {
589629 deleteButton .addClickListener (new ClickListener () {
590630 @ Override
591631 public void buttonClick (ClickEvent event ) {
592- scheduleDel = scheduleFacade . getSchedule (schId );
632+ scheduleDel = getSchedule (schId );
593633
594634 //open confirmation dialog
595635 ConfirmDialog .show (UI .getCurrent (), Messages .getString ("Scheduler.delete.scheduling" ),
596636 Messages .getString ("Scheduler.delete.scheduling.description" , scheduleDel .getPipeline ().getName ().toString ()), Messages .getString ("Scheduler.delete.scheduling.deleteButton" ), Messages .getString ("Scheduler.delete.scheduling.calcelButton" ),
597637 new ConfirmDialog .Listener () {
598- private static final long serialVersionUID = 1L ;
599-
600- @ Override
601- public void onClose (ConfirmDialog cd ) {
602- if (cd .isConfirmed ()) {
603- scheduleFacade .delete (scheduleDel );
604- refreshData ();
605- }
606- }
607- });
638+ private static final long serialVersionUID = 1L ;
639+
640+ @ Override
641+ public void onClose (ConfirmDialog cd ) {
642+ if (cd .isConfirmed ()) {
643+ scheduleFacade .delete (scheduleDel );
644+ refreshData ();
645+ }
646+ }
647+ });
608648 }
609649 });
610650 if (canDelete (schedule )) {
@@ -616,9 +656,9 @@ public void onClose(ConfirmDialog cd) {
616656 }
617657
618658 private void setScheduleEnabled (Long schId , boolean enabled ) {
619- Schedule schedule = scheduleFacade . getSchedule (schId );
659+ Schedule schedule = getSchedule (schId );
620660 schedule .setEnabled (enabled );
621- scheduleFacade .save (schedule );
661+ this . scheduleFacade .save (schedule );
622662 }
623663
624664 boolean canDelete (Schedule schedule ) {
@@ -663,36 +703,6 @@ private void changeURI(Long scheduleId) {
663703 ((AppEntry ) UI .getCurrent ()).setUriFragment (handler .getUriFragment (), false );
664704 }
665705
666- @ Override
667- public Object enter () {
668- if (!isMainLayoutInitialized ) {
669- buildMainLayout ();
670- isMainLayoutInitialized = true ;
671- }
672- setCompositionRoot (mainLayout );
673-
674- refreshManager = ((AppEntry ) UI .getCurrent ()).getRefreshManager ();
675- refreshManager .addListener (RefreshManager .SCHEDULER , new Refresher .RefreshListener () {
676- private long lastRefreshFinished = 0 ;
677-
678- @ Override
679- public void refresh (Refresher source ) {
680- if (new Date ().getTime () - lastRefreshFinished > RefreshManager .MIN_REFRESH_INTERVAL ) {
681- boolean hasModifiedExecutions = pipelineFacade .hasModifiedExecutions (lastLoad );
682- if (hasModifiedExecutions ) {
683- lastLoad = new Date ();
684- refreshData ();
685- }
686- LOG .debug ("Scheduler refreshed." );
687- lastRefreshFinished = new Date ().getTime ();
688- }
689- }
690- });
691- refreshManager .triggerRefresh ();
692-
693- return this ;
694- }
695-
696706 @ Override
697707 public void setParameters (Object configuration ) {
698708 if (configuration != null && Map .class .isAssignableFrom (configuration .getClass ())) {
@@ -767,7 +777,7 @@ public void showDebugEventHandler(long scheduleId) {
767777 if (!schedulerTable .getItemIds ().contains ((new Long (scheduleId )).intValue ())) {
768778 return ;
769779 }
770- Schedule schedule = scheduleFacade . getSchedule (scheduleId );
780+ Schedule schedule = getSchedule (scheduleId );
771781 if (schedule == null ) {
772782 Notification .show (Messages .getString ("Scheduler.0" , scheduleId ), Notification .Type .ERROR_MESSAGE );
773783 return ;
@@ -782,4 +792,45 @@ public void pageChangedHandler(Integer newPageNumber) {
782792 ((AppEntry ) UI .getCurrent ()).setUriFragment (handler .getUriFragment (), false );
783793 }
784794
795+ /**
796+ * Get cached schedule or retrieve from database
797+ *
798+ * @param scheduleId
799+ * @return copy of schedule
800+ */
801+ private Schedule getSchedule (long scheduleId ) {
802+ if (this .scheduleCache .size () >= CACHE_MAX_SIZE ) {
803+ LOG .debug ("Light pipeline cache size exceeded, reloading ..." );
804+ reloadScheduleCache ();
805+ }
806+
807+ if (this .lightCacheLastReload .before (new Date (new Date ().getTime () - CACHE_TIMEOUT ))) {
808+ LOG .debug ("Light pipeline cache timeout, reloading ..." );
809+ reloadScheduleCache ();
810+ }
811+
812+ Schedule schedule = null ;
813+ if (this .scheduleCache .containsKey (scheduleId )) {
814+ schedule = this .scheduleCache .get (scheduleId );
815+ } else {
816+ schedule = this .scheduleFacade .getSchedule (scheduleId );
817+ this .scheduleCache .put (scheduleId , schedule );
818+ }
819+
820+ return schedule ;
821+ }
822+
823+ private void reloadScheduleCache () {
824+ this .scheduleCache .clear ();
825+ this .lightCacheLastReload = new Date ();
826+ }
827+
828+ private void reloadScheduleCache (List <Schedule > schedules ) {
829+ this .scheduleCache .clear ();
830+ for (Schedule schedule : schedules ) {
831+ scheduleCache .put (schedule .getId (), schedule );
832+ }
833+ this .lightCacheLastReload = new Date ();
834+ }
835+
785836}
0 commit comments