private synchronized void generateParams(SchedullerPackage schedullerPackage) { schedullerPackage.messageId = generateMessageId(); schedullerPackage.seqNo = generateSeqNo(); schedullerPackage.idGenerationTime = getCurrentTime(); schedullerPackage.relatedMessageIds.add(schedullerPackage.messageId); schedullerPackage.generatedMessageIds.add(schedullerPackage.messageId); }
public void onMessageConfirmed(long msgId) { for (SchedullerPackage schedullerPackage : messages.values().toArray(new SchedullerPackage[0])) { if (schedullerPackage.state == STATE_SENT) { if (schedullerPackage.relatedMessageIds.contains(msgId)) { schedullerPackage.state = STATE_CONFIRMED; } } } }
public void resendMessage(long msgId) { for (SchedullerPackage schedullerPackage : messages.values().toArray(new SchedullerPackage[0])) { if (schedullerPackage.relatedMessageIds.contains(msgId)) { // schedullerPackage.relatedMessageIds.clear(); schedullerPackage.state = STATE_QUEUED; schedullerPackage.lastAttemptTime = 0; } } }
private synchronized ArrayList<SchedullerPackage> actualPackages(int contextId) { ArrayList<SchedullerPackage> foundedPackages = new ArrayList<SchedullerPackage>(); long time = getCurrentTime(); for (SchedullerPackage schedullerPackage : messages.values().toArray(new SchedullerPackage[0])) { if (schedullerPackage.queuedToChannel != -1 && contextId != schedullerPackage.queuedToChannel) { continue; } boolean isPendingPackage = false; if (schedullerPackage.ttlTime <= getCurrentTime()) { forgetMessage(schedullerPackage.id); continue; } if (schedullerPackage.state == STATE_QUEUED) { if (schedullerPackage.scheduleTime <= time) { isPendingPackage = true; } } else if (schedullerPackage.state == STATE_SENT) { if (getCurrentTime() <= schedullerPackage.expiresTime) { if (schedullerPackage.serialized == null || schedullerPackage.serialized.length < BIG_MESSAGE_SIZE) { if (getCurrentTime() - schedullerPackage.lastAttemptTime >= RETRY_TIMEOUT) { isPendingPackage = true; } } } } if (isPendingPackage) { if (schedullerPackage.serialized == null) { try { if (schedullerPackage.isRpc) { schedullerPackage.serialized = wrapper.wrapObject((TLMethod) schedullerPackage.object).serialize(); } else { schedullerPackage.serialized = schedullerPackage.object.serialize(); } } catch (IOException e) { Logger.e(TAG, e); forgetMessage(schedullerPackage.id); continue; } } foundedPackages.add(schedullerPackage); } } return foundedPackages; }
public void resetSession() { lastMessageId = 0; lastDependId = 0; seqNo = 0; currentMessageGeneration.clear(); for (SchedullerPackage schedullerPackage : messages.values().toArray(new SchedullerPackage[0])) { schedullerPackage.idGenerationTime = 0; schedullerPackage.dependMessageId = 0; schedullerPackage.messageId = 0; schedullerPackage.seqNo = 0; } }
public void unableToSendMessage(long messageId) { for (SchedullerPackage schedullerPackage : messages.values().toArray(new SchedullerPackage[0])) { if (schedullerPackage.state == STATE_SENT) { boolean contains = false; for (Long relatedMsgId : schedullerPackage.relatedMessageIds) { if (relatedMsgId == messageId) { contains = true; break; } } if (contains) { schedullerPackage.state = STATE_QUEUED; } } } }
public void resendAsNewMessageDelayed(long msgId, int delay) { for (SchedullerPackage schedullerPackage : messages.values().toArray(new SchedullerPackage[0])) { if (schedullerPackage.relatedMessageIds.contains(msgId)) { schedullerPackage.idGenerationTime = 0; schedullerPackage.dependMessageId = 0; schedullerPackage.messageId = 0; schedullerPackage.seqNo = 0; schedullerPackage.state = STATE_QUEUED; schedullerPackage.scheduleTime = getCurrentTime() + delay; Logger.d(TAG, "Resending as new #" + schedullerPackage.id); } } }
public synchronized PreparedPackage doSchedule(int contextId, boolean isInited) { ArrayList<SchedullerPackage> foundedPackages = actualPackages(contextId); synchronized (confirmedMessages) { if (foundedPackages.size() == 0 && (confirmedMessages.size() <= MAX_ACK_COUNT || (System.nanoTime() - firstConfirmTime) < CONFIRM_TIMEOUT)) { return null; } } boolean useHighPriority = false; for (SchedullerPackage p : foundedPackages) { if (p.priority == PRIORITY_HIGH) { useHighPriority = true; break; } } ArrayList<SchedullerPackage> packages = new ArrayList<SchedullerPackage>(); if (useHighPriority) { Logger.d("Scheduller", "Using high priority scheduling"); int totalSize = 0; for (SchedullerPackage p : foundedPackages) { if (p.priority == PRIORITY_HIGH) { packages.add(p); totalSize += p.serialized.length; if (totalSize > MAX_WORKLOAD_SIZE) { break; } } } } else { int totalSize = 0; for (SchedullerPackage p : foundedPackages) { packages.add(p); Logger.d( "Scheduller", "Prepare package: " + p.supportTag + " of size " + p.serialized.length); totalSize += p.serialized.length; Logger.d("Scheduller", "Total size: " + totalSize); if (totalSize > MAX_WORKLOAD_SIZE) { break; } } } Logger.d(TAG, "Iteration: count: " + packages.size() + ", confirm:" + confirmedMessages.size()); Logger.d(TAG, "Building package"); if (foundedPackages.size() == 0 && confirmedMessages.size() != 0) { Long[] msgIds; synchronized (confirmedMessages) { msgIds = confirmedMessages.toArray(new Long[confirmedMessages.size()]); confirmedMessages.clear(); } MTMsgsAck ack = new MTMsgsAck(msgIds); Logger.d(TAG, "Single msg_ack"); try { return new PreparedPackage( generateSeqNoWeak(), generateMessageId(), ack.serialize(), useHighPriority); } catch (IOException e) { Logger.e(TAG, e); return null; } } else if (foundedPackages.size() == 1 && confirmedMessages.size() == 0) { SchedullerPackage schedullerPackage = foundedPackages.get(0); schedullerPackage.state = STATE_SENT; if (schedullerPackage.idGenerationTime == 0) { generateParams(schedullerPackage); } Logger.d( TAG, "Single package: #" + schedullerPackage.id + " " + schedullerPackage.supportTag + " (" + schedullerPackage.messageId + ", " + schedullerPackage.seqNo + ")"); schedullerPackage.writtenToChannel = contextId; schedullerPackage.lastAttemptTime = getCurrentTime(); return new PreparedPackage( schedullerPackage.seqNo, schedullerPackage.messageId, schedullerPackage.serialized, useHighPriority); } else { MTMessagesContainer container = new MTMessagesContainer(); if ((confirmedMessages.size() > 0 && !useHighPriority) || (!isInited)) { try { Long[] msgIds; synchronized (confirmedMessages) { msgIds = confirmedMessages.toArray(new Long[0]); confirmedMessages.clear(); } MTMsgsAck ack = new MTMsgsAck(msgIds); Logger.d(TAG, "Adding msg_ack: " + msgIds.length); container .getMessages() .add(new MTMessage(generateMessageId(), generateSeqNoWeak(), ack.serialize())); } catch (IOException e) { Logger.e(TAG, e); } } for (SchedullerPackage schedullerPackage : packages) { schedullerPackage.state = STATE_SENT; if (schedullerPackage.idGenerationTime == 0) { generateParams(schedullerPackage); } if (schedullerPackage.isDepend) { if (schedullerPackage.dependMessageId == 0) { if (lastDependId > 0) { schedullerPackage.dependMessageId = lastDependId; } else { schedullerPackage.dependMessageId = -1; } } lastDependId = schedullerPackage.messageId; } schedullerPackage.writtenToChannel = contextId; schedullerPackage.lastAttemptTime = getCurrentTime(); if (schedullerPackage.isDepend && schedullerPackage.dependMessageId > 0) { Logger.d( TAG, "Adding package: #" + schedullerPackage.id + " " + schedullerPackage.supportTag + " (" + schedullerPackage.messageId + " on " + schedullerPackage.dependMessageId + ", " + schedullerPackage.seqNo + ")"); MTInvokeAfter invokeAfter = new MTInvokeAfter(schedullerPackage.dependMessageId, schedullerPackage.serialized); try { container .getMessages() .add( new MTMessage( schedullerPackage.messageId, schedullerPackage.seqNo, invokeAfter.serialize())); } catch (IOException e) { Logger.e(TAG, e); // Never happens } } else { Logger.d( TAG, "Adding package: #" + schedullerPackage.id + " " + schedullerPackage.supportTag + " (" + schedullerPackage.messageId + ", " + schedullerPackage.seqNo + ")"); container .getMessages() .add( new MTMessage( schedullerPackage.messageId, schedullerPackage.seqNo, schedullerPackage.serialized)); } } long containerMessageId = generateMessageId(); int containerSeq = generateSeqNoWeak(); for (SchedullerPackage schedullerPackage : packages) { schedullerPackage.relatedMessageIds.add(containerMessageId); } Logger.d(TAG, "Sending Package (" + containerMessageId + ", " + containerSeq + ")"); try { return new PreparedPackage( containerSeq, containerMessageId, container.serialize(), useHighPriority); } catch (IOException e) { // Might not happens Logger.e(TAG, e); return null; } } }
public int postMessageDelayed( TLObject object, boolean isRpc, long timeout, int delay, int contextId, boolean highPrioroty) { int id = messagesIds.incrementAndGet(); SchedullerPackage schedullerPackage = new SchedullerPackage(id); schedullerPackage.object = object; schedullerPackage.addTime = getCurrentTime(); schedullerPackage.scheduleTime = schedullerPackage.addTime + delay; schedullerPackage.expiresTime = schedullerPackage.scheduleTime + timeout; schedullerPackage.ttlTime = schedullerPackage.scheduleTime + timeout * 2; schedullerPackage.isRpc = isRpc; schedullerPackage.queuedToChannel = contextId; schedullerPackage.priority = highPrioroty ? PRIORITY_HIGH : PRIORITY_NORMAL; schedullerPackage.isDepend = highPrioroty; schedullerPackage.supportTag = object.toString(); messages.put(id, schedullerPackage); return id; }