Skip to content

Instantly share code, notes, and snippets.

@leviyehonatan
Created October 3, 2012 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leviyehonatan/3827592 to your computer and use it in GitHub Desktop.
Save leviyehonatan/3827592 to your computer and use it in GitHub Desktop.
merge won't work on a collection
package com.dodedooh.jobdispatcher.data;
import java.util.List;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.TypedQuery;
import com.dodedooh.jobdispatcher.model.Image;
import com.dodedooh.jobdispatcher.model.JobProcessor;
import com.dodedooh.jobdispatcher.model.RenderJob;
import com.dodedooh.jobdispatcher.model.RenderJobSlice;
import com.dodedooh.jobdispatcher.model.Template;
import com.dodedooh.shared.Stages;
@Stateless
// @TransactionAttribute(TransactionAttributeType.REQUIRED)
public class GeneralDAO {
@Inject
Logger log;
@PersistenceContext
private EntityManager em;
// images
public List<Image> getImages() {
TypedQuery<Image> imagesQuery = em.createQuery("select i from Image i", Image.class);
return imagesQuery.getResultList();
}
public Image getImage(int id) {
return (Image) em.find(Image.class, id);
}
public void addImage(Image image) {
em.persist(image);
}
// templates
public void addTemplate(Template template) {
em.persist(template);
}
public List<Template> getTemplates() {
TypedQuery<Template> templatesQuery = em.createQuery("select t from Templates t", Template.class);
return templatesQuery.getResultList();
}
public com.dodedooh.shared.Template getSharedTemplate(int templateId) {
return em.find(com.dodedooh.shared.Template.class, templateId);
}
public Template getTemplate(int templateId) {
return em.find(Template.class, templateId);
}
public Template getTemplateByClientId(int templateId) {
return em.createQuery("select t ServerTemplate t where t.template.id = :templateid", Template.class)
.setParameter("templateid", templateId).getSingleResult();
}
// job processor
public void addJobProcessor(JobProcessor jobProcessor) {
em.persist(jobProcessor);
}
public void updateJobProcessor(JobProcessor jobProcessor) {
em.merge(jobProcessor);
}
public JobProcessor getJobProcessor(String jobProcessorId) {
return em.find(JobProcessor.class, jobProcessorId);
}
public List<JobProcessor> getDeadJobProcessors() {
return em.createQuery("from JobProcessor jp where jp.dead = true", JobProcessor.class).getResultList();
}
public List<JobProcessor> getAvailableJobProcessors() {
return em.createQuery("select jp from JobProcessor jp where jp.assignedSlice is null", JobProcessor.class)
.getResultList();
}
public void updateJobProcessorLastUpdate(String jobProcessorId) {
em.createQuery("update JobProcessor jp set lastUpdate = :currenttime where jp.id = :jobProcessorId")
.setParameter("currenttime", System.currentTimeMillis()).setParameter("jobProcessorId", jobProcessorId)
.executeUpdate();
}
public void updateDeadJobProcessors(long timeout) {
int setDead = em
.createQuery(
"update JobProcessor jp set dead = true, assignedSlice = null where :currenttime-jp.lastUpdate > :timeout and jp.dead=false")
.setParameter("currenttime", System.currentTimeMillis()).setParameter("timeout", timeout)
.executeUpdate();
if (setDead > 0) {
log.info(setDead + " job processors were set dead");
}
}
public void updateJobProcessorsDontDie() {
em.createQuery("update JobProcessor jp set lastUpdate = :currenttime")
.setParameter("currenttime", System.currentTimeMillis()).executeUpdate();
}
// render jobs
public RenderJob getRenderJob(int renderJobId) {
return em.find(RenderJob.class, renderJobId);
}
public List<RenderJob> getRenderJobs() {
return em.createQuery("from ServerRenderJob", RenderJob.class).getResultList();
}
public List<RenderJob> getRenderJobsWithSlices() {
return em.createQuery("select rj from ServerRenderJob rj left join fetch rj.slices", RenderJob.class)
.getResultList();
}
// public List<RenderJob> getAwaitingRenderJobs() {
// return
// em.createQuery("from ServerRenderJob srj where srj.currentStage == :stage",
// RenderJob.class).setParameter("stage", Stages.Queue).getResultList();
// }
public void addRenderJob(RenderJob renderJob) {
em.persist(renderJob);
}
public void updateRenderJob(RenderJob renderJob) {
em.merge(renderJob);
}
// render job slice
public RenderJobSlice getRenderJobSlice(int renderJobSliceId) {
return em.find(RenderJobSlice.class, renderJobSliceId);
}
public List<RenderJobSlice> getUnassignedSlices() {
return em.createQuery(
"select rjs from ServerRenderJobSlice rjs "
+ "where rjs.assignedJobProcessor = null and rjs.dataSaved = false", RenderJobSlice.class)
.getResultList();
}
}
public void sliceJob(RenderJob renderJob) {
RenderOptions renderOptions = renderJob.getRenderJob().getRenderOptions() != null ? renderJob.getRenderJob().getRenderOptions() : currentRenderOptions;
List<JobProcessor> available = dao.getAvailableJobProcessors();
RenderJobSlicer slicer = new RenderJobSlicer();
List<com.dodedooh.shared.jobprocessor.RenderJobSlice> jpSlices = null;
if (renderJob.getRenderJob().isProfile()) {
jpSlices = slicer.sliceForProfile(renderJob.getRenderJob());
} else {
switch (renderOptions.getSlicingScheme()) {
case Chunks:
jpSlices = slicer.sliceChunks(renderJob.getRenderJob(), renderOptions.getChunkSize());
case Profiled:
if (available.size() < renderOptions.getMinimumSlices()) {
break;
}
long intervals[] = templateManager.calcProfileIntervals(renderJob.getRenderJob().getTemplateId());
if (intervals == null) {
log.info("Profile does not exist, wait until its done.");
} else {
jpSlices = slicer.sliceProfiled(renderJob.getRenderJob(), available.size(), intervals);
}
break;
}
}
// create server slices accordingly.
List<RenderJobSlice> slices = new ArrayList<RenderJobSlice>();
for (com.dodedooh.shared.jobprocessor.RenderJobSlice jpSlice : jpSlices) {
RenderJobSlice slice = new RenderJobSlice();
slice.setRenderJobSlice(jpSlice);
slice.setRenderJob(renderJob);
slices.add(slice);
}
renderJob.setSlices(slices);
renderJob.setCurrentStage(Stages.Render);
dao.updateRenderJob(renderJob);
}
package com.dodedooh.jobdispatcher.model;
import java.util.UUID;
import java.util.logging.Logger;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Transient;
import com.dodedooh.shared.jobprocessor.JobProcessorStatus;
@Entity
public class JobProcessor {
/**
* each instance of the server side representation of a job processor
* receives a unique id so it can be identified. practically this is a
* session-id.
*/
@Id
private String id;
/**
* this is the address of this job processor
*/
private String address;
/**
* last update from the job processor of its different statuses.
*/
@Transient
private JobProcessorStatus status = null;
/**
* refers to the assigned render job slice
*/
@OneToOne(cascade=CascadeType.ALL)
private RenderJobSlice assignedSlice = null;
/**
* specifies if the job has been sent to the jobprocessor already.
*/
private boolean processingStarted;
/**
* this is the keep-alive
*/
private long lastUpdate;
/**
* if there has been no update from this job processor we will tag is as dead.
*/
private boolean dead;
public boolean isDead() {
return dead;
}
public void setDead(boolean dead) {
this.dead = dead;
}
public JobProcessor() {
id = UUID.randomUUID().toString();
status = null;
assignedSlice = null;
processingStarted = false;
}
/**
* @param address
* address of the jobprocessor
*/
public JobProcessor(String address) {
this();
this.address = address;
}
/**
* @return multi-dimensional array of statueses, actually an array of
* key-value array, where key is renderJobID and value is string
* which represents current state.
*/
public JobProcessorStatus getStatus() {
return status;
}
public void setStatus(JobProcessorStatus status) {
this.status = status;
}
public com.dodedooh.shared.jobprocessor.RenderJobSlice getRenderJobSlice() {
if (assignedSlice != null && processingStarted == false) {
processingStarted = true;
return assignedSlice.getRenderJobSlice();
}
return null;
}
public boolean isProcessingStarted() {
return processingStarted;
}
/**
* @return true if this jobprocessor is available for processing currently
* this means that there is no other jobs running.
*/
public boolean isAvailable() {
return assignedSlice == null;
}
// getter/setter
public String getAddress() {
return address;
}
public RenderJobSlice getAssignedSlice() {
return assignedSlice;
}
public void setAssignedSlice(RenderJobSlice assignedSlice) {
this.assignedSlice = assignedSlice;
this.processingStarted = false;
}
public String getId() {
return id;
}
public long getLastUpdate() {
return lastUpdate;
}
public void setLastUpdate(long lastUpdate) {
this.lastUpdate = lastUpdate;
}
public String toString() {
return id + " @" + address + " assigned slice: " + (assignedSlice == null ? "unassigned" : assignedSlice);
}
}
package com.dodedooh.jobdispatcher.model;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import com.dodedooh.shared.RenderJobLog;
import com.dodedooh.shared.Stages;
@Entity(name="ServerRenderJob")
public class RenderJob {
@Id @GeneratedValue
private int id;
@OneToOne(cascade=CascadeType.ALL)
private com.dodedooh.shared.RenderJob renderJob;
@OneToMany(mappedBy="renderJob", cascade=CascadeType.ALL)
private List<RenderJobSlice> slices;
private Stages currentStage;
@OneToOne(cascade=CascadeType.ALL)
private RenderJobLog renderJobLog;
public RenderJob() {
this.renderJobLog = new RenderJobLog();
renderJobLog.addEvent("created");
this.currentStage = Stages.Queue;
}
public void setRenderJob(com.dodedooh.shared.RenderJob renderJob) {
this.renderJob = renderJob;
}
public int getId() {
return id;
}
public List<RenderJobSlice> getSlices() {
return slices;
}
public void setSlices(List<RenderJobSlice> slices) {
this.slices = slices;
}
public RenderJobLog getRenderJobLog() {
return renderJobLog;
}
public void setRenderJobLog(RenderJobLog renderJobLog) {
this.renderJobLog = renderJobLog;
}
public Stages getCurrentStage() {
return currentStage;
}
public void setCurrentStage(Stages currentStage) {
this.currentStage = currentStage;
}
public com.dodedooh.shared.RenderJob getRenderJob() {
return renderJob;
}
public void addRenderLogEvent(String stage) {
renderJobLog.addEvent(stage);
}
public String toString() {
return "id: " + id + " clientRenderJob: " + renderJob + " stage: " + currentStage + (slices == null ? "" : " slices: " + slices.size());
}
}
package com.dodedooh.jobdispatcher.model;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import com.dodedooh.shared.RenderJobLog;
@Entity(name="ServerRenderJobSlice")
public class RenderJobSlice {
@Id
@GeneratedValue
private int id;
@OneToOne(cascade=CascadeType.ALL)
private com.dodedooh.shared.jobprocessor.RenderJobSlice renderJobSlice;
@ManyToOne(cascade=CascadeType.ALL)
private RenderJob renderJob;
@OneToOne(mappedBy="assignedSlice", cascade=CascadeType.ALL)
private JobProcessor assignedJobProcessor;
private boolean dataSaved;
@OneToOne(cascade=CascadeType.ALL)
private RenderJobLog log;
public RenderJobSlice() {
}
public int getId() {
return id;
}
public JobProcessor getAssignedJobProcessor() {
return assignedJobProcessor;
}
public void setAssigned(JobProcessor assignedJobProcessor) {
this.assignedJobProcessor = assignedJobProcessor;
}
public com.dodedooh.shared.jobprocessor.RenderJobSlice getRenderJobSlice() {
return renderJobSlice;
}
public void setRenderJobSlice(com.dodedooh.shared.jobprocessor.RenderJobSlice renderJobSlice) {
this.renderJobSlice = renderJobSlice;
}
public RenderJob getRenderJob() {
return renderJob;
}
public void setRenderJob(RenderJob renderJob) {
this.renderJob = renderJob;
}
public boolean isDataSaved() {
return dataSaved;
}
public void setDataSaved(boolean dataSaved) {
this.dataSaved = dataSaved;
}
public boolean isJobProcessorAssigned() {
return assignedJobProcessor != null;
}
public String toString() {
return "RenderJobSlice" + renderJobSlice + " datasaved: " + dataSaved
+ (isJobProcessorAssigned() ? " assigned" : " unassigned");
}
public RenderJobLog getLog() {
return log;
}
public void setLog(RenderJobLog log) {
this.log = log;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment