Add update to array based Scheduler

Hi,

I am trying to build some kind of caching code for scheduler. The reason is the very slow database query (because of many data). So I don’t want the scheduler to reload all the data after any action.

For that I load the data into an array once. Now I am planning to update only the data stored in the array. After a special button action the array data will be stored into the database.

So I implemented the array based scheduler:

public class DataServlet extends ConnectorServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		OptionsConnector sections = new OptionsConnector(null);
		sections.servlet(request, response);
		sections.set_encoding("utf-8");
		try {
			sections.render_array(mySectionArray, "value", "value,label,item");

			SchedulerConnector scheduler = new SchedulerConnector(null);
			scheduler.set_encoding("utf-8");
			scheduler.servlet(request, response);
			scheduler.set_options("sections", sections);

			scheduler.render_array(myEventArray, "event_id",	"start_date,end_date,event_text,section_id");
			scheduler.event.attach(new CustomBehavior());
		} catch (SQLException e) {
		}
	}

	@Override
	protected void configure() {
	}
}

class CustomBehavior extends ConnectorBehavior{ @Override public void beforeUpdate(DataAction data) { if (data.get_value("name").equals("")) data.invalid(); } }

$(function() {
	init();
});

function init() {

	scheduler.locale.labels.timeline_tab = "Timeline";
	scheduler.locale.labels.section_custom="Section";
	scheduler.config.details_on_create=true;
	scheduler.config.details_on_dblclick=true;
	scheduler.config.xml_date="%Y-%m-%d %H:%i";

	var sections = scheduler.serverList("sections");
	scheduler.createTimelineView({
		name:	"timeline",
		x_unit:	"minute",
		x_date:	"%H:%i",
		x_step:	SCHEDULER_TIME_COLUMN_WIDTH_IN_MINUTES,
		x_size: SCHEDULER_COUNT_TIME_COLUMNS,
		x_start: SCHEDULER_COUNT_START_TIME_IN_HOURS_PER_DAY,
		x_length: SCHEDULER_TIME_COLUMNS_TO_SCROLL_AT_ONCE,
		y_unit:	sections,
		y_property:	"section_id",
		render:"bar"
	});

	scheduler.config.lightbox.sections=[
		{name:"description", height:130, map_to:"text", type:"textarea" , focus:true},
		{name:"custom", height:23, type:"select", options:sections, map_to:"section_id" },
		{name:"time", height:72, type:"time", map_to:"auto"}
	];

	scheduler.init('scheduler_here',new Date(1985,9,21),"timeline");
	scheduler.load(URL_DATA_SERVLET);
	
	var dp = new dataProcessor(URL_DATA_SERVLET);
	dp.init(scheduler);
}

The scheduler is shown very well. But when I update one event the servlet calls an exception at “section.render_array()”. I thought with enabling a CustomBehavior (which has no function yet, it’s just for testing if the method can be called) to the scheduler the update routine will end up in the beforeUpdate override of the CustomBehavior. But it never reaches. Instead the update will render all the data again.

The exception

FATAL: Servlet.service() for servlet [DataServlet] in context with path [/myproject] threw exception
java.lang.NullPointerException
	at com.dhtmlx.connector.DBDataWrapper.update_query(DBDataWrapper.java:294)
	at com.dhtmlx.connector.DBDataWrapper.update(DBDataWrapper.java:278)
	at com.dhtmlx.connector.DataProcessor.check_exts(DataProcessor.java:279)
	at com.dhtmlx.connector.DataProcessor.inner_process(DataProcessor.java:222)
	at com.dhtmlx.connector.DataProcessor.process(DataProcessor.java:127)
	at com.dhtmlx.connector.BaseConnector.render(BaseConnector.java:411)
	at com.dhtmlx.connector.BaseConnector.render_array(BaseConnector.java:394)
	at com.dhtmlx.connector.BaseConnector.render_array(BaseConnector.java:367)
	at myproject.HTMLServlet.DataServlet.doGet(DataServlet.java:26)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

Now I am searching for a way to update the array data via dataProcessor or a CustomBehavior.

Or is there a way to get this caching out of the box?

Best regards,
Mark

Edit:
I found the caching function:

dataProcessor.setUpdateMode("OFF");
--> dataProcessor.sendData()

This solved my caching problem but I am still not able to store the changes in the array. Do I need a second “UpdateServlet” which shares the data with the DataServlet? But then I am wondering what are the CustomBehavior classes for?

Hello,
make sure you attach events before calling render methods, otherwise the connector will process the request before an event is attachedscheduler.event.attach(new CustomBehavior()); scheduler.render_array(myEventArray, "event_id", "start_date,end_date,event_text,section_id");
You can also use different configs for get and post requests:

if(scheduler.is_select_mode()){ // select data scheduler.render_array(...); } else{ // update data, update sql scheduler.render_table(...) }
As for the original issue with keeping cache array. Probably the simplest approach would be to listen to the CRUD events of connector
docs.dhtmlx.com/connector__java_ … pdate.html
docs.dhtmlx.com/connector__java_ … elete.html
docs.dhtmlx.com/connector__java_ … nsert.html
In case of ‘delete’ you simply remove an event from your cache array, and for update/insert - you update item from the DataAction argument.
Please note that you can download the class reference of connector library here docs.dhtmlx.com/connector__java__reference.html - Full API reference

As an alternative approach, have you tried using dynamic loading? docs.dhtmlx.com/scheduler/loadin … micloading
It usually speeds up data loading a lot. Note that you’ll need to use it with connector.render_table/render_sql

Hi, thanks for your reply. But my problem is that the exception is raising on rendering the sections-Part. The process never reaches the scheduler rendering. How to I pass the sections renderin if the CustomBehavior is attached to the later called scheduler renderer?

Hi,

thank you. Putting the attach line before the render call does the job.

  1. Does it make a difference if you use the afterUpdate or the beforeUpdate event interceptor? I was using the before method but you linked the after one. I thought I should intercept the handling before it starts. In my opinion you call it after some work has been done.

  2. During the event handling - no matter if before oder afterUpdate - I handle the given event data. But sometimes it is neccesary to manipulate other events. Maybe if one event changes its section, a second one has to change too. So I would change the array data. How do I trigger the update for the scheduler? Or is there a way to trigger an event manually server side for a scheduler event?

Hello.

“beforeUpdate” event happens before updatating data in database and it can be canceled. “afterUpdate” event happens after updating data in database and cannot be canceled.
If your data somehow changes after some event updating you could add some specific property to response. ( See article: docs.dhtmlx.com/connector__java_ … ssing.html )
On the client side you could handle onAfterUpdate dataprocessor event. docs.dhtmlx.com/api__refs__dataprocessor.html
In this one you could check response and if this one contains your specific property you could clear scheduler data and load again from server.