Skip to content

Commit 09bd97c

Browse files
authored
Merge pull request #470 from classtranscribe/staging
Production
2 parents 6897d4e + e3afbee commit 09bd97c

File tree

10 files changed

+133
-101
lines changed

10 files changed

+133
-101
lines changed

ClassTranscribeDatabase/Globals.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ public class AppSettings
2626

2727
public string RABBITMQ_PORT { get; set; } = "5672";
2828

29+
public string RABBITMQ_AUTOMATIC_RECOVERY = "true";
30+
public string RABBITMQ_HEARTBEAT_SECONDS = "60";
31+
32+
2933
// RABBITMQ_PREFETCH_COUNT has been replaced with these CONCURRENT LIMITS-
3034
//no longer used g RABBITMQ_PREFETCH_COUNT { get; set; } // No longer used; can be deleted in next cleanup
3135
public string MAX_CONCURRENT_TRANSCRIPTIONS { get; set; }

ClassTranscribeDatabase/Seed.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
using ClassTranscribeDatabase.Models;
2-
using Microsoft.AspNetCore.Identity;
3-
using Microsoft.EntityFrameworkCore;
4-
using Microsoft.Extensions.Logging;
5-
using System;
1+
using System;
62
using System.Collections.Generic;
73
using System.IO;
84
using System.Linq;
9-
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
using Microsoft.AspNetCore.Identity;
8+
using Microsoft.EntityFrameworkCore;
9+
using Microsoft.Extensions.Logging;
10+
11+
using ClassTranscribeDatabase.Models;
1012

1113
namespace ClassTranscribeDatabase
1214
{
@@ -58,7 +60,10 @@ public void Seed()
5860
if (attempt < maxAttempts)
5961
{
6062
_logger.LogInformation($"Sleeping for {retrySeconds} seconds");
61-
Thread.Sleep(1000 * retrySeconds);
63+
// Thread.Sleep(1000 * retrySeconds);
64+
65+
Task.Delay(TimeSpan.FromSeconds(retrySeconds)).Wait();
66+
6267
}
6368
else
6469
{

ClassTranscribeDatabase/Services/RabbitMQConnection.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,18 @@ private void CreateSharedConnection()
6262
ConnectionRefCount++;
6363
return;
6464
}
65-
Logger.LogInformation("Creating RabbitMQ connection");
65+
var recovery = Convert.ToBoolean(Globals.appSettings.RABBITMQ_AUTOMATIC_RECOVERY);
66+
var heartbeat = Convert.ToUInt32(Globals.appSettings.RABBITMQ_HEARTBEAT_SECONDS);
67+
Logger.LogInformation($"Creating RabbitMQ connection recovery:{recovery} heartbeat:{heartbeat}");
6668
var factory = new ConnectionFactory()
6769
{
6870

6971
HostName = Globals.appSettings.RABBITMQ_SERVER_NAME.Length > 0 ? Globals.appSettings.RABBITMQ_SERVER_NAME : Globals.appSettings.RabbitMQServer,
7072
UserName = Globals.appSettings.ADMIN_USER_ID,
7173
Password = Globals.appSettings.ADMIN_PASSWORD,
72-
Port = Convert.ToUInt16(Globals.appSettings.RABBITMQ_PORT) // 5672
73-
74+
Port = Convert.ToUInt16(Globals.appSettings.RABBITMQ_PORT), // 5672
75+
AutomaticRecoveryEnabled = recovery,
76+
RequestedHeartbeat = TimeSpan.FromSeconds(heartbeat)
7477
};
7578
// A developer may still want to checkout old code which uses the old env branch
7679
// so just complain loudly for now

ClassTranscribeServer/Controllers/CaptionsController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public async Task<ActionResult<Caption>> PostCaption(Caption modifiedCaption)
108108
};
109109
_context.Captions.Add(newCaption);
110110
await _context.SaveChangesAsync();
111-
_wakeDownloader.UpdateVTTFile(oldCaption.TranscriptionId);
111+
// nope _wakeDownloader.UpdateVTTFile(oldCaption.TranscriptionId);
112112
return newCaption;
113113
}
114114

@@ -337,7 +337,7 @@ public async Task<ActionResult<IEnumerable<Caption>>> PostCaptionFile(IFormFile
337337
await _context.Captions.AddRangeAsync(captions);
338338
await _context.SaveChangesAsync();
339339

340-
_wakeDownloader.UpdateVTTFile(transcription.Id);
340+
//nope _wakeDownloader.UpdateVTTFile(transcription.Id);
341341

342342
return captions;
343343
}

ClassTranscribeServer/Utils/WakeDownloader.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ public virtual void UpdatePlaylist(string playlistId)
3131
Wake(msg);
3232
}
3333

34-
public virtual void UpdateVTTFile(string transcriptionId)
35-
{
36-
JObject msg = new JObject
37-
{
38-
{ "Type", TaskType.GenerateVTTFile.ToString() },
39-
{ "TranscriptionId", transcriptionId }
40-
};
41-
Wake(msg);
42-
}
34+
// public virtual void UpdateVTTFile(string transcriptionId)
35+
// {
36+
// JObject msg = new JObject
37+
// {
38+
// { "Type", TaskType.GenerateVTTFile.ToString() },
39+
// { "TranscriptionId", transcriptionId }
40+
// };
41+
// Wake(msg);
42+
// }
4343

4444
public void UpdateOffering(string offeringId)
4545
{

PythonRpcServer/kaltura.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
KALTURA_PARTNER_ID = int(os.getenv('KALTURA_PARTNER_ID', default=0))
1717
KALTURA_TOKEN_ID = os.getenv('KALTURA_TOKEN_ID', default=None)
1818
KATLURA_APP_TOKEN = os.getenv('KALTURA_APP_TOKEN', default=None)
19-
19+
KALTURA_TIMEOUT= int( os.getenv('KALTURA_TIMEOUT', default=30))
2020

2121
# Examples of Playlists URLs the user is likely to see-
2222
# Playlist 1_eilnj5er is Angrave's short set of example vidos
@@ -181,7 +181,7 @@ def getMediaInfosForKalturaChannel(self, partnerInfo, channelId):
181181
return self.getSensibleMediaInfos(res)
182182

183183
def downloadLecture(self, url):
184-
filePath, extension = download_file(url)
184+
filePath, extension = download_file(url, timeout=KALTURA_TIMEOUT)
185185
return filePath, extension
186186

187187
#Exxpects

PythonRpcServer/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,12 @@ def extension_from_magic_bytes(filepath):
8787
# Filepath and cookies may be specified
8888
# Returns a two tuple, [filepath, extension]
8989
# An appropriate Extension is guessed based on the mimetype in the 'content-type' response header
90-
def download_file(url, filepath=None, cookies=None):
90+
def download_file(url, filepath=None, cookies=None, timeout=60):
9191
# NOTE the stream=True parameter below
9292
if not filepath:
9393
filepath = getTmpFile()
9494
extension = None
95-
with requests.get(url, stream=True, allow_redirects=True, cookies=cookies) as r:
95+
with requests.get(url, stream=True, allow_redirects=True, cookies=cookies, timeout=timeout) as r:
9696

9797

9898
r.raise_for_status()

TaskEngine/Program.cs

Lines changed: 91 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
using ClassTranscribeDatabase;
2-
using ClassTranscribeDatabase.Services;
3-
using ClassTranscribeDatabase.Services.MSTranscription;
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
44
using Microsoft.EntityFrameworkCore;
55
using Microsoft.Extensions.Configuration;
66
using Microsoft.Extensions.DependencyInjection;
77
using Microsoft.Extensions.Logging;
88
using Microsoft.Extensions.Options;
9-
using System;
10-
using TaskEngine.Tasks;
11-
using System.Threading;
9+
1210
using Newtonsoft.Json.Linq;
11+
1312
using static ClassTranscribeDatabase.CommonUtils;
13+
using ClassTranscribeDatabase;
14+
using ClassTranscribeDatabase.Services;
15+
using ClassTranscribeDatabase.Services.MSTranscription;
16+
17+
using TaskEngine.Tasks;
1418

1519
namespace TaskEngine
1620
{
@@ -29,14 +33,32 @@ class Program
2933
public static ServiceProvider _serviceProvider;
3034
public static ILogger<Program> _logger;
3135
public static void Main()
36+
{
37+
Console.WriteLine("TaskEngine.Main starting up -GetConfigurations...");
38+
try {
39+
SetupServices(); // should never return
40+
createTaskQueues();
41+
runQueueAwakerForever();
42+
43+
} catch (Exception e) {
44+
// Some paranoia here; we *should* have a logger and exception handler in place
45+
// So this is only here to catch unexpected startup errors that otherwise might be silent
46+
Console.WriteLine($"Unhandled Exception Caught {e.Message}\n{e}\n");
47+
if(_logger !=null){
48+
_logger.LogError(e, "Unhandled Exception Caught");
49+
}
50+
}
51+
}
52+
public static void SetupServices()
3253
{
3354
var configuration = CTDbContext.GetConfigurations();
3455

3556
// This project relies on Dependency Injection to configure its various services,
3657
// For more info, https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1
3758
// All the services used are configured using the service provider.
59+
Console.WriteLine("SetupServices() - starting");
3860

39-
var serviceProvider = new ServiceCollection()
61+
_serviceProvider = new ServiceCollection()
4062
.AddLogging(builder =>
4163
{
4264
builder.AddConsole();
@@ -80,10 +102,9 @@ public static void Main()
80102
.AddSingleton<TempCode>()
81103
.BuildServiceProvider();
82104

83-
_serviceProvider = serviceProvider;
84-
_logger = serviceProvider.GetRequiredService<ILogger<Program>>();
105+
_logger = _serviceProvider.GetRequiredService<ILogger<Program>>();
85106

86-
Globals.appSettings = serviceProvider.GetService<IOptions<AppSettings>>().Value;
107+
Globals.appSettings = _serviceProvider.GetService<IOptions<AppSettings>>().Value;
87108
TaskEngineGlobals.KeyProvider = new KeyProvider(Globals.appSettings);
88109

89110
AppDomain currentDomain = AppDomain.CurrentDomain;
@@ -92,112 +113,108 @@ public static void Main()
92113
_logger.LogInformation("Seeding database");
93114

94115
// Seed the database, with some initial data.
95-
Seeder seeder = serviceProvider.GetService<Seeder>();
116+
Seeder seeder = _serviceProvider.GetService<Seeder>();
96117
seeder.Seed();
118+
}
97119

98-
_logger.LogInformation("Starting TaskEngine");
120+
121+
static void runQueueAwakerForever() {
122+
_logger.LogInformation("runQueueAwakerForever - start");
123+
QueueAwakerTask queueAwakerTask = _serviceProvider.GetService<QueueAwakerTask>();
99124

125+
int periodicCheck = Math.Max(1,Convert.ToInt32(Globals.appSettings.PERIODIC_CHECK_EVERY_MINUTES));
126+
int initialPauseMinutes = Math.Max(1, Convert.ToInt32(Globals.appSettings.INITIAL_TASKENGINE_PAUSE_MINUTES));
127+
128+
_logger.LogInformation("Periodic Check Every {0} minutes", periodicCheck);
129+
var timeInterval = new TimeSpan(0, periodicCheck, 0);
130+
131+
var initialPauseInterval = new TimeSpan(0, initialPauseMinutes, 0);
132+
_logger.LogInformation("Pausing {0} minutes before first periodicCheck", initialPauseInterval);
100133

134+
// Thread.Sleep(initialPauseInterval);
135+
Task.Delay(initialPauseInterval).Wait();
136+
// Check for new tasks every "timeInterval".
137+
// The periodic check will discover all undone tasks
138+
// TODO/REVIEW: However some tasks also publish the next items
139+
while (true)
140+
{
141+
try {
142+
_logger.LogInformation("Periodic Check");
143+
queueAwakerTask.Publish(new JObject
144+
{
145+
{ "Type", TaskType.PeriodicCheck.ToString() }
146+
});
147+
} catch (Exception e) {
148+
_logger.LogError(e, "Error in Periodic Check");
149+
}
150+
// Thread.Sleep(timeInterval);
151+
Task.Delay(timeInterval).Wait();
152+
_logger.LogInformation("Pausing {0} minutes before next periodicCheck", periodicCheck);
153+
};
154+
}
155+
static void createTaskQueues() {
156+
_logger.LogInformation("createTaskQueues() -starting");
101157
// Delete any pre-existing queues on rabbitMQ.
102-
RabbitMQConnection rabbitMQ = serviceProvider.GetService<RabbitMQConnection>();
158+
RabbitMQConnection rabbitMQ = _serviceProvider.GetService<RabbitMQConnection>();
103159

104160
// Active queues managed by C# (concurrency > 0) are now purged after the queue is created and before messages are processed
105161

106162
ushort concurrent_videotasks = ToUInt16(Globals.appSettings.MAX_CONCURRENT_VIDEO_TASKS, NO_CONCURRENCY);
107163
ushort concurrent_synctasks = ToUInt16(Globals.appSettings.MAX_CONCURRENT_SYNC_TASKS, MIN_CONCURRENCY);
108164
ushort concurrent_transcriptions = ToUInt16(Globals.appSettings.MAX_CONCURRENT_TRANSCRIPTIONS, MIN_CONCURRENCY);
109-
ushort concurrent_describe_images = 1;
110-
ushort concurrent_describe_videos = 1;
111-
165+
ushort concurrent_describe_images = NO_CONCURRENCY;
166+
ushort concurrent_describe_videos = NO_CONCURRENCY;
112167

113168
// Create and start consuming from all queues. If concurrency >=1 the queues are purged
114169

115-
116170
// Upstream Sync related
117171
_logger.LogInformation($"Creating DownloadPlaylistInfoTask & DownloadMediaTask consumers. Concurrency={concurrent_synctasks} ");
118-
serviceProvider.GetService<DownloadPlaylistInfoTask>().Consume(concurrent_synctasks);
119-
serviceProvider.GetService<DownloadMediaTask>().Consume(concurrent_synctasks);
172+
_serviceProvider.GetService<DownloadPlaylistInfoTask>().Consume(concurrent_synctasks);
173+
_serviceProvider.GetService<DownloadMediaTask>().Consume(concurrent_synctasks);
120174

121175
// Transcription Related
122176
_logger.LogInformation($"Creating TranscriptionTask consumers. Concurrency={concurrent_transcriptions} ");
123177

124-
serviceProvider.GetService<TranscriptionTask>().Consume(concurrent_transcriptions);
178+
_serviceProvider.GetService<TranscriptionTask>().Consume(concurrent_transcriptions);
125179

126-
// no more! - serviceProvider.GetService<GenerateVTTFileTask>().Consume(concurrent_transcriptions);
180+
// no more! - _serviceProvider.GetService<GenerateVTTFileTask>().Consume(concurrent_transcriptions);
127181

128182
// Video Processing Related
129183
_logger.LogInformation($"Creating ProcessVideoTask consumer. Concurrency={concurrent_videotasks} ");
130-
serviceProvider.GetService<ProcessVideoTask>().Consume(concurrent_videotasks);
184+
_serviceProvider.GetService<ProcessVideoTask>().Consume(concurrent_videotasks);
131185
// Descriptions
132-
serviceProvider.GetService<DescribeVideoTask>().Consume(concurrent_describe_videos);
133-
serviceProvider.GetService<DescribeImageTask>().Consume(concurrent_describe_images);
134-
135-
186+
_serviceProvider.GetService<DescribeVideoTask>().Consume(concurrent_describe_videos);
187+
_serviceProvider.GetService<DescribeImageTask>().Consume(concurrent_describe_images);
136188

137189
// SceneDetection now handled by native Python
138190
// See https://github.com/classtranscribe/pyapi
139-
serviceProvider.GetService<SceneDetectionTask>().Consume(DISABLED_TASK);
191+
_serviceProvider.GetService<SceneDetectionTask>().Consume(DISABLED_TASK);
140192

141193
// We dont want concurrency for these tasks
142194
_logger.LogInformation("Creating QueueAwakerTask and Box token tasks consumers.");
143-
serviceProvider.GetService<QueueAwakerTask>().Consume(NO_CONCURRENCY); //TODO TOREVIEW: NO_CONCURRENCY?
144-
// does nothing at the moment serviceProvider.GetService<UpdateBoxTokenTask>().Consume(NO_CONCURRENCY);
145-
serviceProvider.GetService<CreateBoxTokenTask>().Consume(NO_CONCURRENCY); // calls _box.CreateAccessTokenAsync(authCode);
195+
_serviceProvider.GetService<QueueAwakerTask>().Consume(NO_CONCURRENCY); //TODO TOREVIEW: NO_CONCURRENCY?
196+
// does nothing at the moment _serviceProvider.GetService<UpdateBoxTokenTask>().Consume(NO_CONCURRENCY);
197+
_serviceProvider.GetService<CreateBoxTokenTask>().Consume(NO_CONCURRENCY); // calls _box.CreateAccessTokenAsync(authCode);
146198

147199
// Elastic Search index should be built after TranscriptionTask
148-
serviceProvider.GetService<BuildElasticIndexTask>().Consume(NO_CONCURRENCY);
200+
_serviceProvider.GetService<BuildElasticIndexTask>().Consume(NO_CONCURRENCY);
149201

150202
// Outdated Elastic Search index would be removed
151-
serviceProvider.GetService<CleanUpElasticIndexTask>().Consume(NO_CONCURRENCY);
203+
_serviceProvider.GetService<CleanUpElasticIndexTask>().Consume(NO_CONCURRENCY);
152204

153-
serviceProvider.GetService<ExampleTask>().Consume(NO_CONCURRENCY);
205+
_serviceProvider.GetService<ExampleTask>().Consume(NO_CONCURRENCY);
154206

155-
serviceProvider.GetService<PythonCrawlerTask>().Consume(DISABLED_TASK);
156-
157-
_logger.LogInformation("Done creating task consumers");
158-
//nolonger used :
159-
// nope serviceProvider.GetService<nope ConvertVideoToWavTask>().Consume(concurrent_videotasks);
160-
161-
bool hacktest = false;
162-
if (hacktest)
163-
{
164-
TempCode tempCode = serviceProvider.GetService<TempCode>();
165-
tempCode.Temp();
166-
return;
167-
}
168-
_logger.LogInformation("All done!");
169-
170-
QueueAwakerTask queueAwakerTask = serviceProvider.GetService<QueueAwakerTask>();
171-
172-
int periodicCheck = Math.Max(1,Convert.ToInt32(Globals.appSettings.PERIODIC_CHECK_EVERY_MINUTES));
173-
int initialPauseMinutes = Math.Max(1, Convert.ToInt32(Globals.appSettings.INITIAL_TASKENGINE_PAUSE_MINUTES));
174-
175-
_logger.LogInformation("Periodic Check Every {0} minutes", periodicCheck);
176-
var timeInterval = new TimeSpan(0, periodicCheck, 0);
177-
178-
var initialPauseInterval = new TimeSpan(0, initialPauseMinutes, 0);
179-
_logger.LogInformation("Pausing {0} minutes before first periodicCheck", initialPauseInterval);
180-
181-
Thread.Sleep(initialPauseInterval);
182-
183-
// Check for new tasks every "timeInterval".
184-
// The periodic check will discover all undone tasks
185-
// TODO/REVIEW: However some tasks also publish the next items
186-
while (true)
187-
{
188-
queueAwakerTask.Publish(new JObject
189-
{
190-
{ "Type", TaskType.PeriodicCheck.ToString() }
191-
});
192-
Thread.Sleep(timeInterval);
193-
};
207+
_serviceProvider.GetService<PythonCrawlerTask>().Consume(DISABLED_TASK);
208+
_logger.LogInformation("createTaskQueues() - Done creating task consumers");
194209
}
195-
196210
// Catch all unhandled exceptions.
197211
static void ExceptionHandler(object sender, UnhandledExceptionEventArgs args)
198212
{
199213
Exception e = (Exception)args.ExceptionObject;
200-
_logger.LogError(e, "Unhandled Exception Caught");
214+
Console.WriteLine($"Unhandled Exception Caught {e.Message}\n{e}\nSender:{sender ?? "null"}");
215+
if(_logger !=null){
216+
_logger.LogError(e, "Unhandled Exception Caught");
217+
}
201218
}
202219

203220
private static ushort ToUInt16(String val, ushort defaultVal)

0 commit comments

Comments
 (0)