RoomClient was mooved to the DB while I implemented cluster. Current changes only make the calls faster (since DB is quered only once)
I'll try to create couple of tests. Right now I think the current code should work faster or the same as previous one. Old code did lots of full filterings of RommsClient hash map to get subset required. I tests will show I'm wrong on this I'll try to tune up openjpa cache and if it doesn't help will split RoomClient to the couple of objects and/or will create hashtable in parallel to speed up things. But I hope everything is not so slow since these changes are present in 2.0 and nobody reports performance degradation. Sorry for typos, I'm from mobile phone On Oct 19, 2012 9:11 PM, "[email protected]" <[email protected]> wrote: > I guess this happened lately in trunk. > How are we the in the future planning to determine the current users in > the room. > Session or database based? > > I ask that critical as some queries require to sync messages to all > clients of a room. > This can happen 1000 times in a single second if you think about having up > to 1000 concurrent user sessions. > > For example: > ScopeApplicationAdapter::syncMessageToCurrentScope(String > remoteMethodName, Object newMessage, boolean sendSelf, boolean sendScreen) > => Collection<Set<IConnection>> conCollection = current.getScope() > .getConnections(); > ==> iterates through all connection of the scope. > > Now the new thing is that for every connection you will create a query for > the RoomClient Object. > This is simply impossible. > > We want to scale up to 1000 concurrent user sessions and more. > The RoomClient is a typical Session object and it should stay in the > session. > It is the same issue like with the WhiteboardObject. > We are making a real time application, there is no chance to run queries > in sync methods. > > Can we find some consens here? I know you must have refactored already a > lot but I strictly did implement zero db related stuff in sync methods. > > There might be a chance for some events to trigger db actions.However I > don't think having two times the RoomClient stored (one time session, > second time database) makes sense. > > What are you thoughts on this? > > Sebastian > > 2012/10/19 [email protected] <[email protected]> > >> Hi Maxim, >> >> I don't understand this new code in the Rooms Entity: >> @OneToMany(fetch = FetchType.LAZY) >> >> @JoinColumn(name = "room_id") >> private List<RoomClient> currentusers; >> >> We calc the current users online by iterating through the Red5 >> Connections. >> In which OpenMeetings version was it changed? >> >> I guess you can set it Transient for XML export/import. So maybe annotate >> it with: >> @org.simpleframework.xml.Transient >> same like roomOrganisations. >> >> Sebastian >> >> 2012/10/19 <[email protected]> >> >> Author: solomax >>> Date: Fri Oct 19 12:39:38 2012 >>> New Revision: 1400075 >>> >>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev >>> Log: >>> Wicket: calendar form is improved >>> >>> Modified: >>> >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java >>> >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java >>> >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java >>> >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html >>> >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java >>> >>> Modified: >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java >>> URL: >>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff >>> >>> ============================================================================== >>> --- >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java >>> (original) >>> +++ >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java >>> Fri Oct 19 12:39:38 2012 >>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro >>> return q.getSingleResult(); >>> } >>> >>> + public List<Rooms> getPublicRooms() { >>> + //TypedQuery<Rooms> q = >>> em.createNamedQuery("getNondeletedRooms", Rooms.class); >>> + TypedQuery<Rooms> q = em.createQuery( >>> + "SELECT r from Rooms r LEFT JOIN FETCH >>> r.currentusers WHERE r.ispublic= true and r.deleted= false ORDER BY >>> r.name ASC", Rooms.class); >>> + return q.getResultList(); >>> + } >>> + >>> + public List<Rooms> getOrganisationRooms(long orgId) { >>> + TypedQuery<Rooms> q = em.createQuery( >>> + "SELECT DISTINCT c.room FROM >>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH >>> c.room.currentusers " >>> + + "WHERE c.organisation.organisation_id = :orgId " >>> + + "AND c.deleted = false AND c.room.deleted = false " >>> + + "AND c.organisation.deleted = false " >>> + + "ORDER BY c.room.name ASC", Rooms.class); >>> + q.setParameter("orgId", orgId); >>> + return q.getResultList(); >>> + } >>> + >>> public Rooms update(Rooms entity, long userId) { >>> if (entity.getRooms_id() == null) { >>> /* Red5SIP integration >>> *******************************************************************************/ >>> >>> Modified: >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java >>> URL: >>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff >>> >>> ============================================================================== >>> --- >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java >>> (original) >>> +++ >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java >>> Fri Oct 19 12:39:38 2012 >>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery; >>> import javax.persistence.OneToMany; >>> import javax.persistence.OneToOne; >>> import javax.persistence.Table; >>> -import javax.persistence.Transient; >>> >>> import org.apache.openjpa.persistence.ElementDependent; >>> import org.apache.openmeetings.persistence.beans.OmEntity; >>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab >>> private String name; >>> >>> @Lob >>> - // @Basic(fetch=FetchType.LAZY) >>> @Column(name = "comment_field") >>> @Element(data = true, required = false) >>> private String comment; >>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab >>> @org.simpleframework.xml.Transient >>> private List<Rooms_Organisation> roomOrganisations = new >>> ArrayList<Rooms_Organisation>(); >>> >>> - /* >>> - * Non persistent attributes >>> - */ >>> - @Transient >>> + @OneToMany(fetch = FetchType.LAZY) >>> + @JoinColumn(name = "room_id") >>> private List<RoomClient> currentusers; >>> >>> public String getComment() { >>> >>> Modified: >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java >>> URL: >>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff >>> >>> ============================================================================== >>> --- >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java >>> (original) >>> +++ >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java >>> Fri Oct 19 12:39:38 2012 >>> @@ -18,14 +18,36 @@ >>> */ >>> package org.apache.openmeetings.web.components.user.calendar; >>> >>> +import java.util.ArrayList; >>> +import java.util.List; >>> + >>> +import >>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl; >>> +import org.apache.openmeetings.data.conference.RoomDAO; >>> +import org.apache.openmeetings.data.conference.Roommanagement; >>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl; >>> import org.apache.openmeetings.persistence.beans.calendar.Appointment; >>> +import >>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps; >>> +import >>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users; >>> +import org.apache.openmeetings.persistence.beans.rooms.RoomTypes; >>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms; >>> +import org.apache.openmeetings.web.app.Application; >>> +import org.apache.openmeetings.web.app.WebSession; >>> +import org.apache.wicket.ajax.AjaxRequestTarget; >>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox; >>> +import org.apache.wicket.extensions.yui.calendar.DateTimeField; >>> +import org.apache.wicket.markup.html.form.ChoiceRenderer; >>> +import org.apache.wicket.markup.html.form.DropDownChoice; >>> import org.apache.wicket.markup.html.form.Form; >>> +import org.apache.wicket.markup.html.form.PasswordTextField; >>> import org.apache.wicket.markup.html.form.RequiredTextField; >>> import org.apache.wicket.markup.html.form.TextArea; >>> +import org.apache.wicket.markup.html.form.TextField; >>> import org.apache.wicket.model.IModel; >>> +import org.apache.wicket.model.PropertyModel; >>> >>> public class CalendarForm extends Form<Appointment> { >>> private static final long serialVersionUID = >>> -1764738237821487526L; >>> + private boolean createRoom = true; >>> >>> public CalendarForm(String id, IModel<Appointment> model) { >>> super(id, model); >>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A >>> >>> add(new RequiredTextField<String>("appointmentName")); >>> add(new TextArea<String>("appointmentDescription")); >>> + add(new TextField<String>("appointmentLocation")); >>> + add(new DateTimeField("appointmentStarttime")); >>> + add(new DateTimeField("appointmentEndtime")); >>> + final PasswordTextField pwd = new >>> PasswordTextField("password"); >>> + pwd.setEnabled(isPwdProtected()); >>> + pwd.setOutputMarkupId(true); >>> + add(pwd); >>> + >>> + add(new DropDownChoice<AppointmentReminderTyps>( >>> + "remind" >>> + , >>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList() >>> + , new >>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId"))); >>> + >>> + final DropDownChoice<RoomTypes> roomType = new >>> DropDownChoice<RoomTypes>( >>> + "room.roomtype" >>> + , >>> Application.getBean(Roommanagement.class).getAllRoomTypes() >>> + , new ChoiceRenderer<RoomTypes>("name", >>> "roomtypes_id")); >>> + roomType.setEnabled(createRoom); >>> + roomType.setOutputMarkupId(true); >>> + add(roomType); >>> + >>> + final DropDownChoice<Rooms> room = new >>> DropDownChoice<Rooms>( >>> + "room" >>> + , getRoomList() >>> + , new ChoiceRenderer<Rooms>("name", >>> "rooms_id")); >>> + room.setEnabled(!createRoom); >>> + room.setOutputMarkupId(true); >>> + add(room); >>> + >>> + add(new AjaxCheckBox("createRoom", new >>> PropertyModel<Boolean>(this, "createRoom")) { >>> + private static final long serialVersionUID = >>> -3743113990890386035L; >>> + >>> + @Override >>> + protected void onUpdate(AjaxRequestTarget >>> target) { >>> + createRoom = getConvertedInput(); >>> + >>> target.add(roomType.setEnabled(createRoom), room.setEnabled(!createRoom)); >>> + } >>> + }); >>> + add(new AjaxCheckBox("isPasswordProtected") { >>> + private static final long serialVersionUID = >>> 6041200584296439976L; >>> + >>> + @Override >>> + protected void onUpdate(AjaxRequestTarget >>> target) { >>> + >>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput()); >>> + pwd.setEnabled(isPwdProtected()); >>> + target.add(pwd); >>> + } >>> + }); >>> + } >>> + >>> + private boolean isPwdProtected() { >>> + return >>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected()); >>> + } >>> + >>> + private List<Rooms> getRoomList() { >>> + //FIXME need to be reviewed >>> + List<Rooms> result = new ArrayList<Rooms>(); >>> + RoomDAO dao = Application.getBean(RoomDAO.class); >>> + result.addAll(dao.getPublicRooms()); >>> + for (Organisation_Users ou : >>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users()) >>> { >>> + >>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id())); >>> + } >>> + if (getModelObject().getRoom() != null && >>> getModelObject().getRoom().getAppointment()) { //FIXME review >>> + result.add(getModelObject().getRoom()); >>> + } >>> + return result; >>> } >>> } >>> >>> Modified: >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html >>> URL: >>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff >>> >>> ============================================================================== >>> --- >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html >>> (original) >>> +++ >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html >>> Fri Oct 19 12:39:38 2012 >>> @@ -71,7 +71,7 @@ >>> $('#appointment').dialog({ >>> closeOnEscape: true >>> , resizable: true >>> - , width: 400 >>> + , width: 450 >>> , autoOpen: false >>> , modal: true >>> }); >>> @@ -89,53 +89,55 @@ >>> <td><wicket:ommessage >>> key="572" /></td> >>> <td><input type="text" >>> wicket:id="appointmentName" /></td> >>> </tr> >>> - <!-- tr> >>> - <td> </td> >>> - <td> >>> - >>> <wicket:ommessage key="570" /><input type="text" >>> wicket:id="appointmentStarttime" /> >>> - >>> <wicket:ommessage key="571" /><input type="text" >>> wicket:id="appointmentEndtime" /> >>> - </td> >>> + <tr> >>> + <td><wicket:ommessage >>> key="570" /></td> >>> + <td><span >>> wicket:id="appointmentStarttime"></span></td> >>> + </tr> >>> + <tr> >>> + <td><wicket:ommessage >>> key="571" /></td> >>> + <td><span >>> wicket:id="appointmentEndtime"></span></td> >>> </tr> >>> <tr> >>> <td><wicket:ommessage >>> key="565" /></td> >>> - <td><select >>> wicket:id="notification" ></select></td> >>> + <td><select >>> wicket:id="remind" ></select></td> >>> </tr> >>> <tr> >>> <td colspan="2"><input >>> type="checkbox" wicket:id="createRoom" /><wicket:ommessage key="1509" >>> /></td> >>> </tr> >>> <tr> >>> <td><wicket:ommessage >>> key="619" /></td> >>> - <td><select >>> wicket:id="roomType" ></select></td> >>> + <td><select >>> wicket:id="room.roomtype" ></select></td> >>> </tr> >>> <tr> >>> <td><wicket:ommessage >>> key="406" /></td> >>> <td><select >>> wicket:id="room" ></select></td> >>> </tr> >>> <tr> >>> - <td colspan="2"><input >>> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage >>> key="1509" /></td> >>> + <td colspan="2"><input >>> type="checkbox" wicket:id="isPasswordProtected" /><wicket:ommessage >>> key="524" /></td> >>> </tr> >>> <tr> >>> <td><wicket:ommessage >>> key="525" /></td> >>> - <td><input type="text" >>> wicket:id="password" /></td> >>> + <td><input >>> type="password" wicket:id="password" /></td> >>> </tr> >>> <tr> >>> <td >>> colspan="2"><wicket:ommessage key="1445" /></td> >>> </tr> >>> + <!-- >>> <tr> >>> <td><wicket:ommessage >>> key="803" /></td> >>> <td><select >>> wicket:id="meetingMember" ></select></td> >>> - </tr> >>> + </tr --> >>> <tr> >>> <td><wicket:ommessage >>> key="569" /></td> >>> <td><input type="text" >>> wicket:id="appointmentLocation" /></td> >>> - </tr--> >>> + </tr> >>> <tr> >>> <td><wicket:ommessage >>> key="573" /></td> >>> - <td><input type="text" >>> wicket:id="appointmentDescription" /></td> >>> + <td><textarea >>> wicket:id="appointmentDescription"></textarea></td> >>> </tr> >>> <!-- tr> >>> <td colspan="2" >>> style="text-align: right"><input type="button" wicket:id="save" /><input >>> type="button" wicket:id="cancel" /></td> >>> - </tr--> >>> + </tr --> >>> </table> >>> </form> >>> </div> >>> >>> Modified: >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java >>> URL: >>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff >>> >>> ============================================================================== >>> --- >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java >>> (original) >>> +++ >>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java >>> Fri Oct 19 12:39:38 2012 >>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP >>> Calendar end = WebSession.getCalendar(); >>> >>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong()); >>> >>> + if (start.equals(end)) { >>> + end.add(Calendar.HOUR_OF_DAY, 1); >>> + } >>> Appointment a = new Appointment(); >>> >>> a.setAppointmentStarttime(start.getTime()); >>> a.setAppointmentEndtime(end.getTime()); >>> >>> >>> >> >> >> -- >> Sebastian Wagner >> https://twitter.com/#!/dead_lock >> http://www.webbase-design.de >> http://www.wagner-sebastian.com >> [email protected] >> > > > > -- > Sebastian Wagner > https://twitter.com/#!/dead_lock > http://www.webbase-design.de > http://www.wagner-sebastian.com > [email protected] > > >
