private StatusModelNotification(StatusModel model, bool isAdded, bool isNew, long statusId) { this.IsNew = isNew; this.IsAdded = isAdded; this.StatusId = statusId; this.StatusModel = model; }
public static async Task<StatusModel> Get(TwitterStatus status) { return GetIfCacheIsAlive(status.Id) ?? await _loader.StartNew(async () => { if (status.GenerateFromJson) { status = await StatusProxy.SyncStatusActivityAsync(status).ConfigureAwait(false); } var rto = status.RetweetedOriginal == null ? null : await Get(status.RetweetedOriginal).ConfigureAwait(false); var lockerobj = _generateLock.GetOrAdd(status.Id, new object()); try { lock (lockerobj) { StatusModel model; WeakReference<StatusModel> wr; _staticCache.TryGetValue(status.Id, out wr); if (wr != null && wr.TryGetTarget(out model)) { return model; } // cache is dead/not cached yet model = new StatusModel(status, rto); wr = new WeakReference<StatusModel>(model); _staticCache[status.Id] = wr; return model; } } finally { _generateLock.TryRemove(status.Id, out lockerobj); // ReSharper disable InvertIf #pragma warning disable 4014 if (Interlocked.Increment(ref _cleanupCount) == CleanupInterval) { Interlocked.Exchange(ref _cleanupCount, 0); Task.Run((Action)CollectGarbages); } #pragma warning restore 4014 // ReSharper restore InvertIf } }).Unwrap().ConfigureAwait(false); }
protected virtual bool AddStatus(StatusModel model, bool isNewArrival) { if (!CheckStatusAdd(model.Status, true)) { return false; } var stamp = model.Status.CreatedAt; Statuses.Insert( i => i.TakeWhile(s => s.Status.CreatedAt > stamp).Count(), model); // check auto trim if (IsAutoTrimEnabled && _statusIdCache.Count > TimelineChunkCount + TimelineChunkCountBounce && Interlocked.Exchange(ref _trimCount, 1) == 0) { TrimTimeline(); } return true; }
private StatusModel(TwitterStatus status, StatusModel retweetedOriginal) : this(status) { RetweetedOriginal = retweetedOriginal; }
protected virtual bool AddStatus(StatusModel model, bool isNewArrival) { // estimate point var stamp = model.Status.CreatedAt; if (this.IsAutoTrimEnabled) { // check status will not be trimmed StatusModel lastModel; if (this.Statuses.TryIndexOf(TimelineChunkCount, out lastModel) && lastModel != null && lastModel.Status.CreatedAt > stamp) { // status is in below of trim offset return false; } } lock (this._statusIdCache) { if (!this._statusIdCache.AddDistinct(model.Status.Id)) { return false; } } this.Statuses.Insert( i => i.TakeWhile(s => s.Status.CreatedAt > stamp).Count(), model); // check auto trim if (this.IsAutoTrimEnabled && this._statusIdCache.Count > TimelineChunkCount + TimelineChunkCountBounce && Interlocked.Exchange(ref this._trimCount, 1) == 0) { this.TrimTimeline(); } return true; }
protected StatusViewModel GenerateStatusViewModel(StatusModel status) { return new StatusViewModel(this, status, CurrentAccounts); }
protected override bool AddStatus(StatusModel model, bool isNewArrival) { var result = base.AddStatus(model, isNewArrival); if (result && isNewArrival) { this.OnNewStatusArrival.SafeInvoke(model.Status); if (this.NotifyNewArrivals) { NotificationService.NotifyNewArrival(model.Status, this); } } return result; }
protected override bool AddStatus(StatusModel model, bool isNewArrival) { var result = base.AddStatus(model, isNewArrival); if (result && isNewArrival) { var handler = OnNewStatusArrival; if (handler != null) handler(model.Status); if (this.NotifyNewArrivals) { NotificationService.NotifyNewArrival(model.Status, this); } } return result; }