The glorious return of the in-view runner
This commit is contained in:
		
							parent
							
								
									f20296bc1b
								
							
						
					
					
						commit
						db88c733b4
					
				@ -26,6 +26,7 @@ class StatorRunner:
 | 
			
		||||
        liveness_file: Optional[str] = None,
 | 
			
		||||
        schedule_interval: int = 30,
 | 
			
		||||
        lock_expiry: int = 300,
 | 
			
		||||
        run_for: int = 0,
 | 
			
		||||
    ):
 | 
			
		||||
        self.models = models
 | 
			
		||||
        self.runner_id = uuid.uuid4().hex
 | 
			
		||||
@ -34,9 +35,11 @@ class StatorRunner:
 | 
			
		||||
        self.liveness_file = liveness_file
 | 
			
		||||
        self.schedule_interval = schedule_interval
 | 
			
		||||
        self.lock_expiry = lock_expiry
 | 
			
		||||
        self.run_for = run_for
 | 
			
		||||
 | 
			
		||||
    async def run(self):
 | 
			
		||||
        self.handled = 0
 | 
			
		||||
        self.started = time.monotonic()
 | 
			
		||||
        self.last_clean = time.monotonic() - self.schedule_interval
 | 
			
		||||
        self.tasks = []
 | 
			
		||||
        # For the first time period, launch tasks
 | 
			
		||||
@ -71,17 +74,21 @@ class StatorRunner:
 | 
			
		||||
                            )
 | 
			
		||||
                            self.handled += 1
 | 
			
		||||
                            space_remaining -= 1
 | 
			
		||||
                # Prevent busylooping
 | 
			
		||||
                await asyncio.sleep(0.1)
 | 
			
		||||
        except KeyboardInterrupt:
 | 
			
		||||
            # Wait for tasks to finish
 | 
			
		||||
            print("Waiting for tasks to complete")
 | 
			
		||||
            while True:
 | 
			
		||||
                self.remove_completed_tasks()
 | 
			
		||||
                if not self.tasks:
 | 
			
		||||
                # Are we in limited run mode?
 | 
			
		||||
                if self.run_for and (time.monotonic() - self.started) > self.run_for:
 | 
			
		||||
                    break
 | 
			
		||||
                # Prevent busylooping
 | 
			
		||||
                await asyncio.sleep(1)
 | 
			
		||||
                await asyncio.sleep(0.5)
 | 
			
		||||
        except KeyboardInterrupt:
 | 
			
		||||
            pass
 | 
			
		||||
        # Wait for tasks to finish
 | 
			
		||||
        print("Waiting for tasks to complete")
 | 
			
		||||
        while True:
 | 
			
		||||
            self.remove_completed_tasks()
 | 
			
		||||
            if not self.tasks:
 | 
			
		||||
                break
 | 
			
		||||
            # Prevent busylooping
 | 
			
		||||
            await asyncio.sleep(0.1)
 | 
			
		||||
        print("Complete")
 | 
			
		||||
        return self.handled
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								stator/views.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								stator/views.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.http import HttpResponse, HttpResponseForbidden
 | 
			
		||||
from django.views import View
 | 
			
		||||
 | 
			
		||||
from stator.models import StatorModel
 | 
			
		||||
from stator.runner import StatorRunner
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RequestRunner(View):
 | 
			
		||||
    """
 | 
			
		||||
    Runs a Stator runner within a HTTP request.
 | 
			
		||||
    For when you're on something serverless.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    async def get(self, request):
 | 
			
		||||
        # Check the token, if supplied
 | 
			
		||||
        if not settings.STATOR_TOKEN:
 | 
			
		||||
            return HttpResponseForbidden("No token set")
 | 
			
		||||
        if request.GET.get("token") != settings.STATOR_TOKEN:
 | 
			
		||||
            return HttpResponseForbidden("Invalid token")
 | 
			
		||||
        # Run on all models
 | 
			
		||||
        runner = StatorRunner(StatorModel.subclasses, run_for=2)
 | 
			
		||||
        handled = await runner.run()
 | 
			
		||||
        return HttpResponse(f"Handled {handled}")
 | 
			
		||||
@ -5,6 +5,7 @@ from django.views.static import serve
 | 
			
		||||
 | 
			
		||||
from activities.views import posts, search, timelines
 | 
			
		||||
from core import views as core
 | 
			
		||||
from stator import views as stator
 | 
			
		||||
from users.views import activitypub, admin, auth, follows, identity, settings
 | 
			
		||||
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
@ -121,6 +122,8 @@ urlpatterns = [
 | 
			
		||||
    path(".well-known/nodeinfo", activitypub.NodeInfo.as_view()),
 | 
			
		||||
    path("nodeinfo/2.0/", activitypub.NodeInfo2.as_view()),
 | 
			
		||||
    path("actor/", activitypub.SystemActorView.as_view()),
 | 
			
		||||
    # Stator
 | 
			
		||||
    path(".stator/", stator.RequestRunner.as_view()),
 | 
			
		||||
    # Django admin
 | 
			
		||||
    path("djadmin/", djadmin.site.urls),
 | 
			
		||||
    # Media files
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user