Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
CIRCLE
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
94
Merge Requests
10
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
bd5473c7
authored
Dec 01, 2014
by
Őry Máté
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lazy loading of fields
parent
c126e61f
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
145 additions
and
4 deletions
+145
-4
circle/circle/settings/production.py
+1
-0
circle/dashboard/tables.py
+39
-1
circle/dashboard/tasks/local_tasks.py
+41
-0
circle/dashboard/templates/dashboard/node-detail/resources.html
+1
-1
circle/dashboard/urls.py
+3
-1
circle/dashboard/views/node.py
+2
-1
circle/dashboard/views/util.py
+57
-0
circle/manager/mancelery.py
+1
-0
No files found.
circle/circle/settings/production.py
View file @
bd5473c7
...
...
@@ -88,3 +88,4 @@ for i in LOCAL_APPS:
LOGGING
[
'loggers'
][
i
]
=
{
'handlers'
:
[
'syslog'
],
'level'
:
level
}
LOGGING
[
'loggers'
][
'djangosaml2'
]
=
{
'handlers'
:
[
'syslog'
],
'level'
:
level
}
LOGGING
[
'loggers'
][
'django'
]
=
{
'handlers'
:
[
'syslog'
],
'level'
:
level
}
DEBUG
=
True
circle/dashboard/tables.py
View file @
bd5473c7
...
...
@@ -16,16 +16,54 @@
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from
__future__
import
absolute_import
from
timeit
import
default_timer
from
django.contrib.auth.models
import
Group
,
User
from
django.utils
import
six
from
django.utils.functional
import
lazy
from
django_tables2
import
Table
,
A
from
django_tables2.columns
import
TemplateColumn
,
Column
,
LinkColumn
from
celery.exceptions
import
TimeoutError
from
vm.models
import
Node
,
InstanceTemplate
,
Lease
from
django.utils.translation
import
ugettext_lazy
as
_
from
django_sshkey.models
import
UserKey
from
dashboard.models
import
ConnectCommand
from
.tasks.local_tasks
import
lazy_column
class
LazyColumnMixin
(
object
):
timeout
=
0.5
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
__args
=
args
self
.
__kwargs
=
kwargs
super
(
LazyColumnMixin
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
render
(
self
,
**
kwargs
):
task
=
lazy_column
.
apply_async
(
args
=
[
self
.
__class__
,
self
.
__args
,
self
.
__kwargs
,
kwargs
],
queue
=
"localhost.man"
)
queued
=
default_timer
()
def
get_result
():
remains
=
max
(
0
,
self
.
timeout
-
(
default_timer
()
-
queued
))
try
:
return
task
.
get
(
timeout
=
remains
)
except
TimeoutError
:
pass
from
.views
import
LazyLoadView
return
LazyLoadView
.
get_link
(
task
.
id
)
return
lazy
(
get_result
,
six
.
text_type
)()
class
LazyTemplateColumn
(
LazyColumnMixin
,
TemplateColumn
):
pass
class
NodeListTable
(
Table
):
...
...
@@ -60,7 +98,7 @@ class NodeListTable(Table):
attrs
=
{
'th'
:
{
'class'
:
'node-list-table-thin'
}},
)
monitor
=
TemplateColumn
(
monitor
=
Lazy
TemplateColumn
(
verbose_name
=
_
(
"Monitor"
),
template_name
=
'dashboard/node-list/column-monitor.html'
,
attrs
=
{
'th'
:
{
'class'
:
'node-list-table-monitor'
}},
...
...
circle/dashboard/tasks/local_tasks.py
0 → 100644
View file @
bd5473c7
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from
manager.mancelery
import
celery
@celery.task
(
bind
=
True
)
def
lazy_evaluator
(
task
,
cls
,
pk
,
prop
):
obj
=
cls
.
objects
.
get
(
pk
=
pk
)
for
i
in
prop
.
split
(
"."
):
if
i
.
endswith
(
"()"
):
prop
=
prop
[:
-
2
]
call
=
True
else
:
call
=
False
obj
=
getattr
(
obj
,
prop
)
if
call
:
obj
=
obj
()
return
obj
@celery.task
(
bind
=
True
)
def
lazy_column
(
task
,
cls
,
clsargs
,
clskwargs
,
kwargs
):
obj
=
cls
(
*
clsargs
,
**
clskwargs
)
# skip over LazyColumnMixin.render
assert
cls
.
__mro__
[
0
]
.
__name__
==
"LazyColumnMixin"
return
cls
.
__mro__
[
1
]
.
render
(
obj
,
**
kwargs
)
circle/dashboard/templates/dashboard/node-detail/resources.html
View file @
bd5473c7
...
...
@@ -8,7 +8,7 @@
<dt>
{% trans "Architecture" %}:
</dt><dd>
{{ node.info.architecture }}
</dd>
<dt>
{% trans "Host IP" %}:
</dt><dd>
{{ node.host.ipv4 }}
</dd>
<dt>
{% trans "Enabled" %}:
</dt><dd>
{{ node.enabled }}
</dd>
<dt>
{% trans "Host online" %}:
</dt><dd>
{{ node
.
online }}
</dd>
<dt>
{% trans "Host online" %}:
</dt><dd>
{{ node
_
online }}
</dd>
<dt>
{% trans "Priority" %}:
</dt><dd>
{{ node.priority }}
</dd>
<dt>
{% trans "Driver Version:" %}
</dt>
<dd>
...
...
circle/dashboard/urls.py
View file @
bd5473c7
...
...
@@ -50,7 +50,7 @@ from .views import (
VmGraphView
,
NodeGraphView
,
NodeListGraphView
,
TransferInstanceOwnershipView
,
TransferInstanceOwnershipConfirmView
,
TransferTemplateOwnershipView
,
TransferTemplateOwnershipConfirmView
,
OpenSearchDescriptionView
,
OpenSearchDescriptionView
,
LazyLoadView
,
)
from
.views.vm
import
vm_ops
,
vm_mass_ops
from
.views.node
import
node_ops
...
...
@@ -224,6 +224,8 @@ urlpatterns = patterns(
name
=
"dashboard.views.token-login"
),
url
(
r'^vm/opensearch.xml$'
,
OpenSearchDescriptionView
.
as_view
(),
name
=
"dashboard.views.vm-opensearch"
),
url
(
r'^lazyload/(?P<token>.*)/$'
,
LazyLoadView
.
as_view
(),
name
=
LazyLoadView
.
url_name
),
)
urlpatterns
+=
patterns
(
...
...
circle/dashboard/views/node.py
View file @
bd5473c7
...
...
@@ -38,7 +38,7 @@ from vm.models import Node, NodeActivity, Trait
from
..forms
import
TraitForm
,
HostForm
,
NodeForm
from
..tables
import
NodeListTable
from
.util
import
AjaxOperationMixin
,
OperationView
,
GraphMixin
from
.util
import
AjaxOperationMixin
,
OperationView
,
GraphMixin
,
lazy
def
get_operations
(
instance
,
user
):
...
...
@@ -100,6 +100,7 @@ class NodeDetailView(LoginRequiredMixin,
context
[
'trait_form'
]
=
form
context
[
'graphite_enabled'
]
=
(
settings
.
GRAPHITE_URL
is
not
None
)
context
[
'node_online'
]
=
lazy
(
self
.
object
,
"online"
,
0.5
)
return
context
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
...
...
circle/dashboard/views/util.py
View file @
bd5473c7
...
...
@@ -20,18 +20,23 @@ import json
import
logging
import
re
from
collections
import
OrderedDict
from
timeit
import
default_timer
from
urlparse
import
urljoin
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
,
Group
from
django.core
import
signing
from
django.core.exceptions
import
PermissionDenied
,
SuspiciousOperation
from
django.core.signing
import
dumps
,
loads
from
django.core.urlresolvers
import
reverse
from
django.contrib
import
messages
from
django.contrib.auth.views
import
redirect_to_login
from
django.db.models
import
Q
from
django.http
import
HttpResponse
,
Http404
,
HttpResponseRedirect
from
django.shortcuts
import
redirect
,
render
from
django.utils
import
six
from
django.utils.functional
import
lazy
as
functional_lazy
from
django.utils.html
import
format_html
from
django.utils.translation
import
ugettext_lazy
as
_
,
ugettext_noop
from
django.views.generic
import
DetailView
,
View
from
django.views.generic.detail
import
SingleObjectMixin
...
...
@@ -43,6 +48,7 @@ from celery.exceptions import TimeoutError
from
common.models
import
HumanReadableException
,
HumanReadableObject
from
..models
import
GroupProfile
,
Profile
from
..forms
import
TransferOwnershipForm
from
..tasks.local_tasks
import
lazy_evaluator
logger
=
logging
.
getLogger
(
__name__
)
saml_available
=
hasattr
(
settings
,
"SAML_CONFIG"
)
...
...
@@ -694,3 +700,54 @@ class TransferOwnershipConfirmView(LoginRequiredMixin, View):
unicode
(
user
),
user
.
pk
,
new_owner
,
key
)
raise
PermissionDenied
()
return
(
instance
,
new_owner
)
class
LazyLoadView
(
View
):
url_name
=
"dashboard.view.lazyload"
@classmethod
def
get_url
(
cls
,
id
):
return
reverse
(
cls
.
url_name
,
kwargs
=
{
'token'
:
dumps
(
id
,
salt
=
cls
.
url_name
,
compress
=
True
)})
@classmethod
def
get_link
(
cls
,
id
):
return
format_html
(
'<a href="{0}" class="lazy-loading">{1}</a>'
,
cls
.
get_url
(
id
),
_
(
"Loading..."
))
def
get
(
self
,
request
,
token
):
id
=
loads
(
token
,
salt
=
self
.
url_name
,
max_age
=
60
*
60
)
try
:
value
=
lazy_evaluator
.
AsyncResult
(
id
)
.
get
(
timeout
=
10
)
except
TimeoutError
:
raise
Http404
()
else
:
return
HttpResponse
(
value
)
def
lazy
(
obj
,
prop
,
timeout
=
None
,
force
=
False
,
types
=
None
):
"""Evaluate callable in the background and return value or html token.
timeout: how much to wait for the result (in secs, counted from queuing)
force: don't wait for result
"""
task
=
lazy_evaluator
.
apply_async
(
args
=
[
obj
.
__class__
,
obj
.
pk
,
prop
],
queue
=
"localhost.man"
)
queued
=
default_timer
()
def
get_result
():
if
timeout
is
not
None
:
remains
=
timeout
-
(
default_timer
()
-
queued
)
else
:
remains
=
None
if
not
force
:
try
:
return
task
.
get
(
timeout
=
remains
)
except
TimeoutError
:
pass
return
LazyLoadView
.
get_link
(
task
.
id
)
if
types
is
None
:
types
=
[
six
.
text_type
]
return
functional_lazy
(
get_result
,
*
types
)()
circle/manager/mancelery.py
View file @
bd5473c7
...
...
@@ -35,6 +35,7 @@ celery = Celery('manager',
'storage.tasks.periodic_tasks'
,
'firewall.tasks.local_tasks'
,
'dashboard.tasks.local_periodic_tasks'
,
'dashboard.tasks.local_tasks'
,
])
celery
.
conf
.
update
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment