MCPcopy
hub / github.com/django/django / save

Method save

django/contrib/sessions/backends/file.py:123–184  ·  view source on GitHub ↗
(self, must_create=False)

Source from the content-addressed store, hash-verified

121 return self.create()
122
123 def save(self, must_create=False):
124 if self.session_key is None:
125 return self.create()
126 # Get the session data now, before we start messing
127 # with the file it is stored within.
128 session_data = self._get_session(no_load=must_create)
129
130 session_file_name = self._key_to_file()
131
132 try:
133 # Make sure the file exists. If it does not already exist, an
134 # empty placeholder file is created.
135 flags = os.O_WRONLY | getattr(os, "O_BINARY", 0)
136 if must_create:
137 flags |= os.O_EXCL | os.O_CREAT
138 fd = os.open(session_file_name, flags)
139 os.close(fd)
140 except FileNotFoundError:
141 if not must_create:
142 raise UpdateError
143 except FileExistsError:
144 if must_create:
145 raise CreateError
146
147 # Write the session file without interfering with other threads
148 # or processes. By writing to an atomically generated temporary
149 # file and then using the atomic os.rename() to make the complete
150 # file visible, we avoid having to lock the session file, while
151 # still maintaining its integrity.
152 #
153 # Note: Locking the session file was explored, but rejected in part
154 # because in order to be atomic and cross-platform, it required a
155 # long-lived lock file for each session, doubling the number of
156 # files in the session storage directory at any given time. This
157 # rename solution is cleaner and avoids any additional overhead
158 # when reading the session data, which is the more common case
159 # unless SESSION_SAVE_EVERY_REQUEST = True.
160 #
161 # See ticket #8616.
162 dir, prefix = os.path.split(session_file_name)
163
164 try:
165 output_file_fd, output_file_name = tempfile.mkstemp(
166 dir=dir, prefix=prefix + "_out_"
167 )
168 renamed = False
169 try:
170 try:
171 os.write(output_file_fd, self.encode(session_data).encode())
172 finally:
173 os.close(output_file_fd)
174
175 # This will atomically rename the file (os.rename) if the OS
176 # supports it. Otherwise this will result in a shutil.copy2
177 # and os.unlink (for example on Windows). See #9084.
178 shutil.move(output_file_name, session_file_name)
179 renamed = True
180 finally:

Callers 2

createMethod · 0.95
asaveMethod · 0.95

Calls 8

createMethod · 0.95
_key_to_fileMethod · 0.95
_get_sessionMethod · 0.80
openMethod · 0.45
closeMethod · 0.45
splitMethod · 0.45
writeMethod · 0.45
encodeMethod · 0.45

Tested by

no test coverage detected